You are on page 1of 138

Oracle Database 12C ~ 18c SQL 개선 사항

Sales Engineering | Oracle Korea | FSI


Dong Kyu O
2019.04

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Oracle 18c = Oracle 12.2.0.2

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Oracle 12c~18c SQL 개선사항

Oracle 12.1 개선사항

Oracle 12.2 개선사항

Oracle 18c 개선사항

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Oracle 12c ~ 18c SQL 개선사항
Oracle 12.1 개선사항
1. Top-N using Row limiting clause

2. Approximate Count Distinct

3. Functions can be defined in the WITH clause

4. Lateral Inline View

5. Using CROSS APPLY and OUTER APPLY Joins

6. Enhanced Oracle Native LEFT OUTER JOIN

7. Concurrent Execution of Union

8. Improved Defaults

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted
Rownum의 한계를 극복하다

1. Top-N using Row limiting clause

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause
 11g까지 Sort된 데이터에 대한 Top-N 기능이 없음으로 order by가 적용된 SQL을 인라인뷰로 감싸고 인라인뷰
외부에서 rownum을 사용해야 하는 불편함을 감수함
 12c 의 Row limiting clause 기능으로 완전한 Top-N 기능을 구현하였음
 Row limiting clause으로 Top-N, Top-Percent, Pagination등을 구현할 수 있음

Syntax
[ OFFSET offset { ROW | ROWS } ]
[ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ]
{ ROW | ROWS } { ONLY | WITH TIES } ]
OFFSET : 시작위치
FETCT : 출력할 건수

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New Test Data
▶ Top-N using Row limiting clause SELECT val
FROM rownum_order_test
OFFSET : 시작위치 ORDER BY val;
Syntax
FETCT : 출력할 건수
[ OFFSET offset { ROW | ROWS } ] VAL
----------
[ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ] 1
{ ROW | ROWS } { ONLY | WITH TIES } ] 1
2
2
3
3
Top-N Test Setup 4
4
CREATE TABLE rownum_order_test ( val NUMBER ); 5
5
INSERT ALL 6
6
INTO rownum_order_test 7
INTO rownum_order_test 7
SELECT level 8

같은 값이 두 개씩 존재함
8
FROM dual 9
CONNECT BY level <= 10; 9
10
10
COMMIT;
20 rows selected.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: Top-N 처리

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: 동일 값 처리

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause:Top Percent 처리

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: Pagination 출력 시작위치는 rowcount + 1

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: Offset을 지정한 Top Percent 처리

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: Bind 변수 사용

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: 제약사항 및 추가정보

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Top-N using Row limiting clause: Top-N 쿼리변환

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Count(Distinct Column)값을 빠르게 추정하라

2. Approximate Count Distinct

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Approximate Count Distinct
syntax 의미
APPROX_COUNT_DISTINCT( expr ) expr 값의 중복을 제거하고 Count한다.
정확한 값이 아니라 추정치 이다.
• APPROX_COUNT_DISTINCT 함수는 숫자 값을 Return 한다.

• APPROX_COUNT_DISTINCT(expr)함수는 COUNT (DISTINCT expr) 함수와 매우 비슷하다.

• 기능적으로는 두 함수가 같지만, APPROX_COUNT_DISTINCT는 정확한 값은 아니고 COUNT (DISTINCT expr) 함수와
미세한 편차가 있다. 정확도 > 97% (신뢰도 95%)

• APPROX_COUNT_DISTINCT는 COUNT (DISTINCT expr) 에 비하여 Resource 부하 량이 적으므로 월등히 빠른 속도를


자랑한다.

• BFILE, BLOB, CLOB, LONG, LONG RAW, NCLOB 등의 컬럼은 expr로 사용할 수 없다.

• APPROX_COUNT_DISTINCT 함수는 null 값을 무시한다.


Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |
SQL 측면-12c New
▶ Approximate Count Distinct : 추정치와 정확한 값의 비교

SELECT APPROX_COUNT_DISTINCT(manager_id) AS "Active Managers"


추정치
FROM employees;

Active Managers Size가 작은 테이블의 경우


--------------- 정확한 값과 차이가 없다
18

SELECT COUNT(DISTINCT manager_id) AS "Active Managers" 정확한 값


FROM employees;

Active Managers
---------------
18

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Approximate Count Distinct: 추정치의 정확도
SELECT prod_id,
APPROX_COUNT_DISTINCT(cust_id) AS "ApprNum of Customers",
COUNT(DISTINCT cust_id) AS "Number of Customers"
FROM sales
GROUP BY prod_id 추정 고객의 수가 정확한 값에 근접함
ORDER BY prod_id;

PROD_ID ApprNum of Customers Number of Customers


---------- --------------------- -------------------
13 2516 2492
14 2030 2039
15 2105 2122
16 2367 2384
추정치
17 2093 2100
18 2975 3028 정확한 값
19 2630 2617
Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |
…생략
SQL 측면-12c New
▶ Approximate Count Distinct: 성능

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


두 개의 테이블과 아우터 조인이 가능하다

3. Enhanced Oracle Native LEFT OUTER JOIN

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Enhanced Oracle Native LEFT OUTER JOIN
 12c 부터 두 개의 테이블과 Outer 조인이 가능해짐
 11g 이하 버전에서 테이블 두 개와 Outer 조인을 시도하면 "ORA-01417: 하나의 테이블은
하나의 다른 테이블과 outer-join할 수 있습니다" 에러발생
 아래의 예제는 12c에서 Departments 테이블을 이용하여 두 테이블에 Outer 조인을
사용했으며 정상적으로 조회된다.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


함수를 SQL에서 선언한다

4. Functions can be defined in the WITH clause

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause
 12c 부터 PL/SQL의 Function 및 Procedure를 SQL의 With절에서 선언할 수 있다.
 SQL에서 Function 및 Procedure를 직접 수행함으로 PL/SQL 프로그램의 관리가 필요 없다.
 SQL에서 Function Call이 일어나는 것에 비해 With절을 사용하는 것이 성능상 유리하다.

Test Data Setup With 절로 함수선언 및 실행


CREATE TABLE t1 AS WITH
SELECT 1 AS id FUNCTION with_function(p_id IN NUMBER) RETURN NUMBER IS
FROM dual BEGIN
CONNECT BY level <= 1000000; RETURN p_id;
END;
SELECT with_function(id)
FROM t1
WHERE rownum = 1
/

WITH_FUNCTION(ID)
-----------------
1

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause: Function 내에서 Procedure 실행가능
WITH
PROCEDURE with_procedure(p_id IN NUMBER) IS
BEGIN
DBMS_OUTPUT.put_line('p_id=' || p_id);
END;

FUNCTION with_function(p_id IN NUMBER) RETURN NUMBER IS


BEGIN
with_procedure(p_id);
RETURN p_id;
END;
SELECT with_function(id)
FROM t1
WHERE rownum = 1
/

WITH_FUNCTION(ID)
-----------------
1

p_id=1
SQL>

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause: PL/SQL 에서 사용할 수 없음(Dynamic SQL은 가능)

BEGIN SET SERVEROUTPUT ON


FOR cur_rec IN (WITH DECLARE
FUNCTION with_function(p_id IN NUMBER) RETURN NUMBER IS l_sql VARCHAR2(32767);
BEGIN l_cursor SYS_REFCURSOR;
RETURN p_id; l_value NUMBER;
END; BEGIN
SELECT with_function(id) l_sql := 'WITH
FROM t1 FUNCTION with_function(p_id IN NUMBER) RETURN NUMBER IS
WHERE rownum = 1) BEGIN
LOOP RETURN p_id;
NULL; END;
END LOOP; SELECT with_function(id)
END; FROM t1
/ WHERE rownum = 1';

ERROR at line 3: OPEN l_cursor FOR l_sql;


ORA-06550: line 3, column 30: FETCH l_cursor INTO l_value;
PL/SQL: ORA-00905: missing keyword DBMS_OUTPUT.put_line('l_value=' || l_value);
ORA-06550: line 2, column 19: CLOSE l_cursor;
PL/SQL: SQL Statement ignored END;
ORA-06550: line 5, column 34: /
PLS-00103: Encountered the symbol ";" when expecting one of the following: l_value=1
loop
PL/SQL procedure successfully completed.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause: PL/SQL 함수와 성능비교

CREATE OR REPLACE FUNCTION normal_function(p_id IN NUMBER) WITH


RETURN NUMBER IS FUNCTION with_function(p_id IN NUMBER) RETURN NUMBER IS
BEGIN BEGIN
RETURN p_id; RETURN p_id;
END; END;
/ SELECT with_function(id)
FROM t1;
SELECT normal_function(id)
FROM t1 ;

WITH_FUNCTION : Time=45 hsecs CPU Time=39 hsecs With 절을 이용하면


NORMAL_FUNCTION: Time=129 hsecs CPU Time=113 hsecs
약 3배 빠름
PL/SQL procedure successfully completed.

SQL>

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause: 함수의 INPUT 값에 따라 output이 항상 동일하다면
Deterministic 과 스칼라 서브쿼리를 사용할 것
SET TIMING ON SET TIMING ON

WITH WITH
FUNCTION slow_function(p_id IN NUMBER) RETURN NUMBER FUNCTION slow_function(p_id IN NUMBER) RETURN NUMBER
DETERMINISTIC IS IS
BEGIN BEGIN
DBMS_LOCK.sleep(1); DBMS_LOCK.sleep(1);
RETURN p_id; RETURN p_id;
END; END;
SELECT (SELECT slow_function(id) FROM dual) SELECT slow_function(id)
FROM t1 FROM t1
WHERE ROWNUM <= 10; WHERE ROWNUM <= 10;
/ /

(SELECTSLOW_FUNCTION(ID)FROMDUAL) SLOW_FUNCTION(ID)
--------------------------------- -----------------
1 1
1 1
…생략 …생략

10 rows selected.
약 10배 빠름 10 rows selected.

Elapsed: 00:00:01.04 Elapsed: 00:00:10.07

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Functions can be defined in the WITH clause: WITH절이 서브쿼리에 존재할 때

반드시 힌트를
사용해야 함
UPDATE t1 a UPDATE /*+ WITH_PLSQL */ t1 a
SET a.id = (WITH SET a.id = (WITH
FUNCTION with_function(p_id IN NUMBER) FUNCTION with_function(p_id IN NUMBER)
RETURN NUMBER IS RETURN NUMBER IS
BEGIN BEGIN
RETURN p_id; RETURN p_id;
END; END;
SELECT with_function(a.id) SELECT with_function(a.id)
FROM dual); FROM dual);
/ /
SET a.id = (WITH
*
ERROR at line 2:
ERROR 발생 1000000 rows updated.

ORA-32034: unsupported use of WITH clause SQL>

SQL>

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


인라인 뷰를 스칼라 서브쿼리처럼 사용한다

5. Lateral Inline Views

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Lateral Inline Views
 12c 부터 Inline View를 Lateral로 선언하면, Inline View 내에서 Main 쿼리 테이블의 컬럼과 조인이 가능해짐
 11g 이하 버전에서 위와 같은 조인을 시도하면 "ORA-00904: Main 쿼리 테이블의 조인 컬럼명 invalid
identifier" 에러발생

11g 12c
SELECT * SELECT *
FROM employees e, FROM employees e,
(SELECT * LATERAL(SELECT *
FROM departments d FROM departments d
WHERE e.department_id = d.department_id); WHERE e.department_id = d.department_id);

ORA-00904: "E"."DEPARTMENT_ID": invalid identifier

에러 없이
정상 처리됨

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Lateral Inline Views 제약사항
 Lateral view에 Pivot이나 Unpivot 절을 사용할 수 없다.
 Lateral view 내에서는 Main 쿼리 컬럼과 아우터 조인을 사용할 수 없다. 12c의 Outer Apply 기능을
사용하면 해결됨.
 뷰 내부에 제약사항을 두어 DML을 허용할지 아니면 특정 조건에서만 허용할 지 결정할 수 있음

WITH READ ONLY : VIEW에 DML을 사용할 수 없음


WITH CHECK OPTION : where 조건에 만족하는 경우만 DML이 발생되며, 조건에 맞지 않는 데이터가 입력되면
‘ORA-01402: view WITH CHECK OPTION where-clause violation’ 에러가 발생한다

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 1999를 구현하다

6. (Cross /Outer) Apply Join

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ (Cross /Outer) Apply Join: Inline View 내에서 Main 쿼리 테이블의 컬럼과 조인이 가능함
 ANSI SQL을 구현함. ( SQL1999 standard )
 Cross Apply : Inner Join
 Outer Apply : Left Outer Join
 (Cross/Outer) Apply를 사용했다면 Lateral 키워드는 사용할 수 없다.

SELECT d.department_name, v.employee_id, v.last_name


FROM departments d
CROSS APPLY (SELECT *
FROM employees e
WHERE e.department_id = d.department_id) v
WHERE d.department_name IN ('Marketing', 'Operations', 'Public Relations')
ORDER BY d.department_name, v.employee_id;

DEPARTMENT_NAME EMPLOYEE_ID LAST_NAME


------------------------------ ----------- 부서명 'Operations‘는 사원이
-------------------------
Marketing 201 Hartstein 한명도 없음으로 출력되지 않음
Marketing 202 Fay
Public Relations 204 Baer

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ (Cross /Outer) Apply Join: Inline View 내에서 Main 쿼리 테이블의 컬럼과 조인이 가능함

SELECT d.department_name, v.employee_id, v.last_name


FROM departments d
OUTER APPLY (SELECT *
FROM employees e
WHERE e.department_id = d.department_id) v
WHERE d.department_name IN ('Marketing', 'Operations', 'Public Relations')
ORDER by d.department_name, v.employee_id;

DEPARTMENT_NAME EMPLOYEE_ID LAST_NAME


------------------------------ ----------- -------------------------
Marketing 201 Hartstein
Marketing 202 Fay
Operations
사원이 없는 부서도 출력됨
Public Relations 204 Baer

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Union의 성능을 두배 이상 빠르게 하라

7. Concurrent Execution of Union

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Concurrent Execution of Union : Union 으로 분리된 SQL들을 동시에 실행함
 Union 을 사용하면 제일 위의 SQL부터 하나씩 실행됨으로 성능이 느림
 12c 부터 Parallel을 사용하면 Union으로 분리된 모든 SQL이 동시에 실행됨
 OPTIMIZER_FEATURE_ENABLED 파라미터 값이 '12.1.0.1‘ 혹은 그 이상의 버전이어야 함
Test Data Setup 통계정보생성
create table test_tbl( id number ); begin
create table test_tbl1( id number ); dbms_stats.gather_table_stats(user, 'TEST_TBL');
create table test_tbl2( id number ); dbms_stats.gather_table_stats(user, 'TEST_TBL1');
create table test_tbl3( id number ); dbms_stats.gather_table_stats(user, 'TEST_TBL2');
dbms_stats.gather_table_stats(user, 'TEST_TBL3');
begin end;
for i in 1..10000
loop
insert into test_tbl values(i);
insert into test_tbl1 values(i);
insert into test_tbl2 values(i);
insert into test_tbl3 values(i);
end loop;

commit;
end loop;
/

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Concurrent Execution of Union : Union 으로 분리된 SQL들을 동시에 실행함
select * from test_tbl a alter table test_tbl parallel 2;
union
select * from test_tbl1 b SQL 다시 실행 Parallel 적용
union --------------------------------------------------------
select * from test_tbl2 c | Id | Operation | Name |
union --------------------------------------------------------
select * from test_tbl3 d; | 0 | CREATE TABLE STATEMENT | |
----------------------------------------- | 1 | LOAD AS SELECT | TEST_TBL4 |
| Id | Operation | Name | | 2 | PX COORDINATOR | |
----------------------------------------- | 3 | PX SEND QC (RANDOM) | :TQ10001 |
| 0 | SELECT STATEMENT | | | 4 | OPTIMIZER STATISTICS GATHERING |TEST_TBL이| Scan 될 때 동시에
| 1 | SORT UNIQUE | | | 5 | SORT UNIQUE |
TEST_TBL1~3 | 도 동시에 Scan됨
| 2 | UNION-ALL | | | 6 | PX RECEIVE | |
| 3 | TABLE ACCESS FULL| TEST_TBL | | 7 | PX SEND HASH | :TQ10000 |
| 4 | TABLE ACCESS FULL| TEST_TBL1 | | 8 | UNION-ALL | |
| 5 | TABLE ACCESS FULL| TEST_TBL2 | | 9 | PX BLOCK ITERATOR | |
| 6 | TABLE ACCESS FULL| TEST_TBL3 | | 10 | TABLE ACCESS FULL | TEST_TBL |
----------------------------------------- | 11 | PX SELECTOR | |
| 12 | TABLE ACCESS FULL | TEST_TBL1 |
| 13 | PX SELECTOR | |
Parallel을 사용하지 | 14 | TABLE ACCESS FULL | TEST_TBL2 |
| 15 | PX SELECTOR | |
않음으로 하나씩 실행됨 | 16 | TABLE ACCESS FULL | TEST_TBL3 |
--------------------------------------------------------

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Concurrent Execution of Union : Union 으로 분리된 SQL들을 동시에 실행함
--------------------------------------------------
select /*+ NO_PQ_CONCURRENT_UNION(@"SET$1") */ a.* | Id | Operation | Name |
from ( select * from test_tbl a --------------------------------------------------
union | 0 | SELECT STATEMENT | |
select * from test_tbl1 b | 1 | PX COORDINATOR | |
union | 2 | PX SEND QC (RANDOM) | :TQ10004 |
select * from test_tbl2 c | 3 | VIEW | |
| 4 | SORT UNIQUE | |
union
| 5 | PX RECEIVE | |
select * from test_tbl3 d | 6 | PX SEND HASH | :TQ10003 |
) a; | 7 | BUFFER SORT | |
| 8 | UNION-ALL | |
| 9 | PX BLOCK ITERATOR | |
| 10 | TABLE ACCESS FULL | TEST_TBL |
| 11 | PX RECEIVE | |
| 12 | PX SEND ROUND-ROBIN| :TQ10000 |
| 13 | PX SELECTOR | |
| 14 | TABLE ACCESS FULL| TEST_TBL1 |
| 15 | PX RECEIVE | |
힌트의 사용으로 | 16 | PX SEND ROUND-ROBIN| :TQ10001 |

하나씩 실행됨 | 17 |
| 18 |
PX SELECTOR | |
TABLE ACCESS FULL| TEST_TBL2 |
| 19 | PX RECEIVE | |
| 20 | PX SEND ROUND-ROBIN| :TQ10002 |
| 21 | PX SELECTOR | |
| 22 | TABLE ACCESS FULL| TEST_TBL3 |
--------------------------------------------------

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


SQL 측면-12c New
▶ Concurrent Execution of Union : Union 으로 분리된 SQL들을 동시에 실행함
테이블이 noparallel 로 적용되고 SQL에 Parallel 힌트를 주지
않았다. 하지만 PQ_CONCURRENT_UNION 힌트를 사용하면 모든
SQL이 동시에 실행 가능하다.
----------------------------------------------
alter table test_tbl noparallel; | Id | Operation | Name |
----------------------------------------------
select /*+ PQ_CONCURRENT_UNION(@"SET$1") */ a.*
| 0 | SELECT STATEMENT | |
from ( select * from test_tbl a | 1 | PX COORDINATOR | |
union | 2 | PX SEND QC (RANDOM) | :TQ10001 |
select * from test_tbl1 b | 3 | SORT UNIQUE | |
union | 4 | PX RECEIVE | |
select * from test_tbl2 c | 5 | PX SEND HASH | :TQ10000 |
union | 6 | UNION-ALL | |
select * from test_tbl3 d | 7 | PX SELECTOR | |
) a; | 8 | TABLE ACCESS FULL| TEST_TBL |
| 9 | PX SELECTOR | |
| 10 | TABLE ACCESS FULL| TEST_TBL1 |
| 11 | PX SELECTOR | |
힌트의 사용으로 PX_RECEIVE Operation이 | 12 | TABLE ACCESS FULL| TEST_TBL2 |
사라짐. 모든 SQL이 동시에 Scan됨. | 13 | PX SELECTOR | |
| 14 | TABLE ACCESS FULL| TEST_TBL3 |
----------------------------------------------

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Default 값을 시퀀스로 지정한다

8. Improved Defaults
• Sequence

• when NULL

• IDENTITY based columns

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
SEQUENCE

c##tkyte%CDB1> create sequence s;


Sequence created.

c##tkyte%CDB1> create table t


2 ( x int default s.nextval primary key,
3 y varchar2(30)
4 )
5 /
Table created.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 42


Improved Defaults
SEQUENCE

c##tkyte%CDB1> insert into t(y) values ('hello world');


1 row created.

c##tkyte%CDB1> select * from t;

X Y
---------- ------------------------------
1 hello world

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 43


Improved Defaults
when NULL

c##tkyte%CDB1> create table t


2 ( x number default s.nextval primary key,
3 y number,
4 z number default on null 42
5 );

Table created.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
when NULL

c##tkyte%CDB1> insert into t (y, z) values ( 55, NULL );


c##tkyte%CDB1> insert into t (y,z) values ( 100, 200 );
c##tkyte%CDB1> insert into t (x,y,z) values (-1,-2,-3);

c##tkyte%CDB1> select * from t;

X Y Z
---------- ---------- ----------
2 55 42
3 100 200
-1 -2 -3

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
Identity Example

ID 속성이 선언된 컬럼의 값이 항상 자동으로 생성

CREATE TABLE t1
(id NUMBER GENERATED AS IDENTITY,
first_name varchar2(30)
);

ID 속성이 선언된 컬럼의 값이 입력되지 않은 경우 자동 생성


CREATE TABLE t2
(id NUMBER GENERATED BY DEFAULT AS IDENTITY
(START WITH 100 INCREMENT BY 10),
first_name varchar2(30)
);

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
IDENTITY

c##tkyte%CDB1> create table t


2 ( x number generated as identity,
3 y number
4 )
5 /
Table created.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
IDENTITY
c##tkyte%CDB1> insert into t (x,y) values (1,100);
insert into t (x,y) values (1,100)
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

c##tkyte%CDB1> insert into t (y) values (200);


1 row created.

c##tkyte%CDB1> select * from t;


X Y
---------- ----------
1 200

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
IDENTITY

c##tkyte%CDB1> create table t


2 ( x number generated by default
3 as identity
4 (start with 42
5 increment by 1000),
6 y number
7 )
8 /

Table created.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Improved Defaults
IDENTITY

c##tkyte%CDB1> insert into t (x,y) values (1,100);


1 row created.

c##tkyte%CDB1> insert into t (y) values (200);


1 row created.

c##tkyte%CDB1> select * from t;

X Y
---------- ----------
1 100
42 200

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Oracle 12c ~ 18c SQL 개선사항

Oracle 12.2 개선사항


1. Longer Identifiers (12.2)

2. Data Conversion and Validation (12.2)

3. List Aggregation Enhancement (12.2)

4. Real Time MView (12.2)

5. External Table Enhancement (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted
ORA-00972 에러를 제거하라
1. Longer Identifiers (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Longer Identifiers

테이블명은 28 bytes

인덱스명은 31 bytes

Oracle 12.1 까지 30 bytes를 넘어서지 못했음

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Longer Identifiers (12.2)

Oracle 12.2 부터 128 bytes 까지 사용 가능

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


데이터 Type 형변환이 가능한가? 불가능한가?

2. Data Conversion and Validation (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 55


Data Conversion and Validation
INSERT INTO TARGET
SELECT TO_NUMBER(COL1), TO_DATE(COL2), ….
FROM SOURCE

에러가 발생한 데이터를 볼 수


없음으로 전체 데이터를 검증 해야함

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 56
Data Conversion and Validation
CREATE TABLE t1 ( ON CONVERSION ERROR 옵션을 이용하여
data VARCHAR2(20) 에러발생시 디폴트 값을 출력함
);

INSERT INTO t1 VALUES ('11111');


INSERT INTO t1 VALUES ('01-JAN-2016'); SELECT TO_NUMBER(data DEFAULT -1 ON CONVERSION ERROR )
INSERT INTO t1 VALUES ('AAAAA'); FROM t1;
COMMIT; *
TO_NUMBER(DATADEFAULT-1ONCONVERSIONERROR)
SELECT TO_NUMBER(data) -----------------------------------------
FROM t1; 11111
-1
ERROR: -1
ORA-01722: invalid number
에러가 발생한 경우 -1을 출력

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 57
Data Conversion and Validation
ON CONVERSION ERROR 옵션을 이용하여
에러발생시 디폴트 값을 출력함

SELECT TO_DATE(data DEFAULT '01-JAN-2000' ON CONVERSION ERROR, 'DD-MON-YYYY' )


FROM t1;

TO_DATE(D
---------
01-JAN-00
01-JAN-16
01-JAN-00

에러가 발생한 경우 2000-01-01을 출력

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 58
Data Conversion and Validation

ON CONVERSION ERROR 옵션을 이용하여


CAST 함수를 이용한 형변환 에러발생시 디폴트 값을 출력함

SELECT CAST(data AS TIMESTAMP DEFAULT NULL ON CONVERSION ERROR, 'DD-MON-YYYY')


FROM t1;

CAST(DATAASTIMESTAMPDEFAULTNULLONCONVERSIONERROR,'DD-MON-YYYY')
---------------------------------------------------------------------------

01-JAN-16 12.00.00.000000000 AM

에러가 발생한 경우 NULL을 출력

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 59
Data Conversion and Validation
형변환이 가능한지 판단함 NUMBER TYPE으로 변환이 가능한지 검사함
1: 형변환 가능
0: 형변환 불가능
SELECT data
FROM t1
WHERE VALIDATE_CONVERSION (data AS NUMBER ) = 1;

DATA
--------------------
11111 변환이 가능한 데이터만 출력함
DATE TYPE으로 변환이 가능한지 검사함

SELECT data
FROM t1
WHERE VALIDATE_CONVERSION(data AS DATE, 'DD-MON-YYYY') = 1;

DATA
--------------------
01-JAN-2016

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 60
같은 그룹은 가로로 펼쳐라

3. List Aggregation Enhancement (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 61


같은 주문번호에 속한 제품을 한 줄로(11.2)
주문번호 제품명
1000 제품1
1000 제품2
1000 제품3 데이터구조
1000 제품4
1000 제품5
1001 제품1

주문번호 제품명
1000 제품1, 제품2, 제품3, 제품4, 제품5 원하는 결과
1001 제품1…..

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 62


같은 주문번호에 속한 제품을 한 줄로 (11.2)
SELECT ORDER_ID
, LTRIM(SYS_CONNECT_BY_PATH (PRODUCT_NAME, ', '), ', ') PRODUCT_NAME
, QUANTITY
FROM (
예전 방식의 코딩
SELECT A.ORDER_ID, C.PRODUCT_NAME
, SUM(B.QUANTITY) OVER(PARTITION BY A.ORDER_ID) QUANTITY
, ROW_NUMBER () OVER (PARTITION BY A.ORDER_ID
ORDER BY C.PRODUCT_NAME) RN
, COUNT (*) OVER (PARTITION BY A.ORDER_ID) CNT
FROM OE.ORDERS A, OE.ORDER_ITEMS B, OE.PRODUCT_INFORMATION C
WHERE A.ORDER_ID = B.ORDER_ID
AND B.PRODUCT_ID = C.PRODUCT_ID
AND A.ORDER_DATE >= TO_DATE('20070101', 'YYYYMMDD')
AND A.ORDER_DATE < TO_DATE('20071231', 'YYYYMMDD'))
WHERE LEVEL = CNT
START WITH RN = 1
CONNECT BY PRIOR ORDER_ID = ORDER_ID
AND PRIOR RN = RN - 1
ORDER_ID PRODUCT_NAME 간단하게 변환할 수 있는 방법은 없을까?
--------- ------------------------------------------------------------
2360 Mouse +WP, Pens - 10/FP
2361 Chemicals - TCS, KB 101/ES, LCD Monitor 9/PM, ...생략
2362 KB 101/ES, LCD Monitor 9/PM, PS 12V /P, PS 220V /L, ...생략
2363 CDW 20/48/I, PS 12V /P, PS 220V /L, ...생략
…생략 Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 63
같은 주문번호에 속한 제품을 한 줄로 (11.2)

LISTAGG 사용 방법(11.2 NEW FEATURE)


SELECT 주문번호,
LISTAGG(제품명, ' , ')
WITHIN GROUP (ORDER BY 제품명)
FROM 주문
WHERE …. ..
GROUP BY 주문번호 ;

주문번호 제품명
1000 제품1
1000 제품2
주문번호 제품명
1000 제품3
1000 제품1, 제품2, 제품3, 제품4, 제품5
1000 제품4
1000 제품5

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 64


같은 주문번호에 속한 제품을 한 줄로 (11.2)
COMMA를 구분자로 사용하라 같은 그룹에 PRODUCT_NAME이
여러 개 있을 때 SORT의 기준 컬럼
SELECT A.ORDER_ID
, SUM(B.QUANTITY) QUANTITY
, LISTAGG(PRODUCT_NAME, ', ' ) WITHIN GROUP ( ORDER BY PRODUCT_NAME )
PROD_NAME
, COUNT(*) CNT
FROM OE.ORDERS A, OE.ORDER_ITEMS B, OE.PRODUCT_INFORMATION C
WHERE A.ORDER_ID = B.ORDER_ID
AND B.PRODUCT_ID = C.PRODUCT_ID
AND A.ORDER_DATE >= TO_DATE('20070101', 'YYYYMMDD')
AND A.ORDER_DATE < TO_DATE('20071231', 'YYYYMMDD')
GROUP BY A.ORDER_ID;
ORDER_ID PRODUCT_NAME
--------- ------------------------------------------------------------
2360 Mouse +WP, Pens - 10/FP
2361 Chemicals - TCS, KB 101/ES, LCD Monitor 9/PM, ...생략
2362 KB 101/ES, LCD Monitor 9/PM, PS 12V /P, PS 220V /L, ...생략
2363 CDW 20/48/I, PS 12V /P, PS 220V /L, ...생략
2364 Envoy IC/58, FG Stock - H
…생략

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 65


LISTAGG 결과건수가 너무 길다면? (12.2 New)

SELECT id, LISTAGG(str,'-') WITHIN GROUP(ORDER BY 1) AS string_created


FROM test
GROUP BY id
결과 길이가 4000 Bytes를
ORA-01489: result of string concatenation is too long 초과하면 에러발생

SELECT id
, LISTAGG(str,'-' ON OVERFLOW TRUNCATE ) WITHIN GROUP(ORDER BY 1) AS string_created
FROM test
GROUP BY id
4000 Bytes를 초과하는
결과는 생략가능
ID STRING_CREATED
-- ------------------------------------------
0 TextXXXXXX-TextXXXXXX-TextXXXXXX-...(1068)
1 TextXXXXXX-TextXXXXXX-TextXXXXXX-...(1069) 1069건이 생략됨
2 TextXXXXXX-TextXXXXXX-TextXXXXXX-...(1069)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 66


LISTAGG 결과건수가 너무 길다면? (12.2 New)
SELECT id
, LISTAGG(str,'-' ON OVERFLOW TRUNCATE ' [more] ') WITHIN GROUP(ORDER BY 1) AS string_created
FROM test
GROUP BY id
4000 Bytes를 초과하는 결과를 생략할 때
‘ [more] ‘를 출력함
ID STRING_CREATED
-- -----------------------------------------------
생략하면 Default로 ‘…’ 가 출력됨
0 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more] (1068)
1 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more] (1069)
2 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more] (1069)

SELECT id
, LISTAGG(str,'-' ON OVERFLOW TRUNCATE ' [more] ' WITHOUT COUNT ) WITHIN GROUP(ORDER BY 1) AS string_created
FROM test
GROUP BY id

ID STRING_CREATED 4000 Bytes를 초과하는 결과를 생략할 때


-- ----------------------------------------------- COUNT를 출력하지 않음
0 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more]
1 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more]
2 TextXXXXXX-TextXXXXXX-TextXXXXXX- [more]
Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 67
실시간 집계를 최소화하라

4. Real Time MView

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Real Time MView (12.2)

70억건 Full Scan + Group By


처리시간이 매우 길어 짐
Time Out 발생!!

그럼 MView를 써볼까?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 69


Real Time MView (12.2)

12.1 버전에서 Mview 생성

1. Source 테이블이 변경되면 Log를


저장한다. 이때 SQL에서 사용할
컬럼을 포함해야 한다.

2. Query Rewrite 옵션으로 MView


생성

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 70


Real Time MView (12.2)

MView를 만든 직후는 t 테이블을 읽는 대신,


집계된 MView를 사용함으로 성능이 매우 빨라 짐

Mview는 Super Hero?

하지만…..

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 71


Real Time MView (12.2)

소스테이블이
소스테이블의 데이터가변경되면
변경되면
Query Rewrite가 안됨
Query Rewrite가 안됨

Mview는 Oracle 12.1 까지는


Super Hero가 아니었음

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 72


Real Time MView (12.2)

• 소스테이블이 변경될 때마다 Mview Refresh가 필요함

• Trigger성 작업으로 인한 부하가 커짐

• Refresh 직후만 Query Rewrite가 작동됨으로 해결책이 아님

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 73


Real Time MView (12.2)

12.2 부터 소스 변경분을
감안한 Mview 등장

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 74


Real Time MView (12.2)

소스 테이블 변경

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 75


Real Time MView (12.2)
1초만에 실행됨
변경 분 반영됨

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 76


Real Time MView (12.2)

Refresh를 하지도 않았는데


성능도 빠르고 변경분이 반영 되었다.
How?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 77


Real Time MView (12.2)

12.1 Basic Refresh 개념도

사용자가 결과를 요청하면 Mview만 이용함.


따라서 변경 건이 발생하면 Mview를 사용하지 못함으로 성능이 저하됨

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 78


Real Time MView (12.2)

12.2 Real Time Refresh 개념도

사용자가 결과를 요청할 때 변경분이 있으면 Mview 로그를 읽음


Mview Log와 Mview 를 Union 하여 결과를 Return 함
실제로 트리거성 Refresh 가 발생하지 않음으로 성능이 향상됨
Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 79
Real Time MView (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 80


Real Time MView (12.2)

• 제약사항
– ENABLE ON QUERY COMPUTATION 옵션을 반드시 사용해야함
– QUERY_REWRITE_INTEGRITY가 ENFORCED (the default) 또는 TRUSTED로 설정되어야 가능함
STALE_TOLERATED는 불가능
– REFRESH … ON COMMIT 옵션과 같이 사용할 수 없음
– Mview 소스테이블은 database link가 될 수 없음
– 소스 테이블에 변경분이 있을 때 Mview를 Direct로 select 하면 변경분이 반영되지 않음
(FRESH_MV 힌트를 사용하면 가능함)

• 유의사항
– Real Time Mview를 사용하더라도 Refresh를 최소화할 뿐이며, 변경분이 많아져서 읽어야 할 Log가
많아지면 성느이 느려짐.
– 성능향상을 위해서 정기적인 Refresh 가 필요함

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 81


External Table을 동적으로 Control한다

5. External Table Enhancement


• Parameter Override

• Partitioning External Tables

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


External Table Parameter Override (12.2)

Ext_tab은 세개의
파일로 구성됨

Modify 가능한
파라미터

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


External Table Parameter Override (12.2)

Location을 수정해서
사용하는 예제

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


(12.2)
Partitioned External Table
• Oracle database의 파티션 테이블과 유사함
• Source files :OS file system, Apache Hive storage, or HDFS

• 장점:
– Partition Pruning으로 성능향상
– 데이터 관리의 편의성
– full and partial partition-wise join이 가능함

• Partitioning 가능한 종류: Primary\Secondary Range List Auto-List Interval

Range Y Y N N
List Y Y N N
Interval N N N N

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 85


(12.2)
Keywords For Partitioned External Table

• PARTITION BY절을 이용하여 정의


– partition by range (c1)

• 각 Partition에 templates 지정 가능함


– partition p1 values less than (7655) location('./tkexpetu_p1a.dat', './tkexpetu_p1b.dat'),
– partition p2 values less than (7845) default directory def_dir2 location('./tkexpetu_p2.dat'),
– partition p3 values less than (7935) location(def_dir3:'./tkexpetu_p3*.dat’)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 86


Example Partitioned External Table (1/2) (12.2)

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 87


Example Partitioned External Table (2/2) (12.2)
create table salesrp_xt_hdfs
(c1 number, c2 number)
organization external (
type oracle_hdfs
default directory def_dir1
access parameters (
com.oracle.bigdata.cluster=hadoop_cl_1
com.oracle.bigdata.fields: (c1 int, c2 int)
com.oracle.bigdata.rowformat=delimited fields terminated by ','))
reject limit unlimited
partition by range (c1) (
partition p1 values less than (7655)
location('./tkexpetu_p1a.dat', './tkexpetu_p1b.dat'),
partition p2 values less than (7845)
default directory def_dir2 location('./tkexpetu_p2.dat'),
partition p3 values less than (7935)
location(def_dir3:'./tkexpetu_p3*.dat’));

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 88


(12.2)

Explain Plan For Accessing Partitioned External Table


select AVG(s.L_PARTKEY) from scott.emp e, salesrp_xt s

Select * from salesrp_xt_hdfs partition (p2) order by c2; where s.l_orderkey = e.sal and e.job = 'SALESMAN';

------------------------------------------------------------------------ --------------------------------------------------------------------------

| Id | Operation | Name | Pstart| Pstop | | Id | Operation | Name | Pstart| Pstop |

------------------------------------------------------------------------ --------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | | 0 | SELECT STATEMENT | | | |

| 1 | SORT ORDER BY | | | | | 1 | SORT AGGREGATE | | | |

| 2 | PARTITION RANGE SINGLE | | 2 | 2 | |* 2 | HASH JOIN | | | |

| 3 | EXTERNAL TABLE ACCESS FULL| SALESRP_XT_HDFS | 2 | 2 | | 3 | JOIN FILTER CREATE | :BF0001 | | |

------------------------------------------------------------------------ | 4 | PART JOIN FILTER CREATE | :BF0000 | | |


|* 5 | TABLE ACCESS FULL | EMP | | |
| 6 | JOIN FILTER USE | :BF0001 | | |
| 7 | PARTITION RANGE JOIN-FILTER| |:BF0000|:BF0000|
|* 8 | EXTERNAL TABLE ACCESS FULL| SALESRP_XT_HDFS |:BF0000|:BF0000|
--------------------------------------------------------------------------
2 - access("S"."L_ORDERKEY"="E"."SAL")
5 - filter("E"."JOB"='SALESMAN')
8 - filter(SYS_OP_BLOOM_FILTER(:BF0001,"S"."L_ORDERKEY"))

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 89


Oracle 12c ~ 18c SQL 개선사항
Oracle 18c 개선사항
1. External Table Enhancement (18c)

2. Private Temporary Tables (18c)

3. Approximate Top-N Queries (18c)

4. ALTER SYSTEM CANCEL SQL (18c)

5. Data Pump Enhancement (18c)

6. Online Partition Maintenance (18c)

7. Scalable Extend Sequence (18c)

8. Memoptimized Rowstore (18c)

Learn more 18c?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted
External Table을 동적으로 Control한다

1. External Table Enhancement


• Inline External Tables

• In-Memory for External Tables

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Inline External Tables
External 테이블을 인라인뷰로 지정함
DDL이 필요 없음

CREATE TABLE sales_xt


(prod_id number, … )
TYPE ORACLE_LOADER
… INSERT INTO sales
LOCATION ’new_sales_kw13') SELECT sales_xt.*
REJECT LIMIT UNLIMITED ); FROM EXTERNAL(
(prod_id number, … )
INSERT INTO sales SELECT * FROM TYPE ORACLE_LOADER
sales_xt; …
LOCATION ’new_sales_kw13')
DROP TABLE sales_xt; REJECT LIMIT UNLIMITED );

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 92


In-Memory For External Tables(1/2)
External Data도 빠른 분석이 가능해짐
External Data RDBMS • External Table을 사용하면 DB 외부의
In-memory In-memory 데이터에 투명하게 액세스 할 수 있음
External Database
Object Storage Tables Tables
• External 데이터를 초고속으로
분석하기 위해 columnar 데이터를 DB
메모리내에 구축함
Files • 기존(12.2 까지)의 모든 In-Memory
최적화 기술이 적용됨
DB TABLES – Vector processing, JSON expression
Hadoop 등의 기능이 External 데이터에
투명하게 확장됨
• 최대 100X 빨라 짐

Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal 93
In-Memory For External Tables(2/2)
External Data도 빠른 분석이 가능해짐 3. External 테이블을 In-Memory
영역에 Loading
1. 파라미터 설정(In-Memory option)
inmemory_size = XXX GB
SQL> exec dbms_inmemory.populate(USER,'S_ET');
create table s_et(
s_suppkey number , PL/SQL procedure successfully completed.
s_name char(25) ,
s_address varchar2(40) , SQL> exec dbms_inmemory.populate(USER,'SUPPLIER');
s_nationkey number ,
s_phone char(15) , PL/SQL procedure successfully completed. 4. External 테이블이 In-Memory
s_acctbal number , 영역에 Loading되었는지 확인
s_comment varchar2(101)
SQL> select
)
organization external ( SEGMENT_NAME,INMEMORY_SIZE,BYTES_NOT_POPULATED,POPULATE_STATUS,IS_EXTERNAL
type ORACLE_LOADER from v$im_segments;
2. External 테이블을 In-Memory +
default directory T_WORK Query High 압축으로 생성
access parameters
( SEGMENT_NAME INMEMORY_SIZE BYTES_NOT_POPULATED POPULATE_STAT IS_EX
records delimited by newline ------------ ------------- ------------------- ------------- -----
nobadfile SUPPLIER 2359296 0 COMPLETED FALSE
nologfile S_ET 2228224 0 COMPLETED TRUE
fields terminated by '|'
missing field values are null
)
location (T_WORK:'supplier.tbl') 5. S_ET 테이블이 IN-MEMORY
) 영역에 로딩완료 되었으며 External
reject limit unlimited 테이블임을 확인함
INMEMORY MEMCOMPRESS FOR QUERY HIGH;

Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 94
세션에서만 존재하는 임시 테이블

2. Private Temporary Tables

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Private Temporary Tables
ACC_TMP Global temporary tables
• 테이블 Layout은 모든 사용자와 모든 세션에 동일함
• 데이터는 세션마다 다름
ACC_TMP ACC_TMP
– Data physically exists for a transaction or session
– Session-private statistics

Private temporary tables (18.1)

ACC_PTMP ACC_PTMP • 같은 테이블명이라 할지라도 세션 혹은 트랜잭션마다


테이블 Layout 을 다르게 설정할 수 있음
– Private table name and shape

• 데이터도 세션마다 다름
– Session or transaction duration

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 96


Private Temporary Tables

오직 세션에서만 존재하는 테이블임

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 97


Private Temporary Tables

에러가 발생하는 이유는?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 98


Private Temporary Tables

Commit 시 테이블
drop이 Default임

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 99


분석쿼리의 상위 N을 높은 정확도로 예측하라

3. Approximate Top-N Queries

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Group by 후 sort가
필요함
Top-N Queries
• 지난해에 가장 많이 팔린 상품 상위 5개를 주(week)단위로 구하라
• 지역별로 소득이 가장 많은 상위 5명을 구하라
• 지난주에 view수 가 가장 많은 5개의 블로그 post를 구하라
• 작년 매출기준으로 상위 50명의 고객은 각각 얼마를 소비했는지
구하라

Sort
Weblog Top-N
Data Read

Sorting는 시간을 많이 소비함


Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 101
Top-N approximate aggregation
• TOP – N 쿼리 검색에 대한 대략적인(Approximate) 검색결과
– View수 가 가장 많은 5개의 블로그 post를 구하라
– 지역별로 지출이 가장 많은 고객 50명을 구하라
• approximate aggregation을 사용하면 쿼리 처리속도도 빠르고 정확도도 높음
(error rate < 0.5%)
• 새로운 approximate functions: APPROX_COUNT(), APPROX_SUM(), APPROX_RANK()
Top 5 blogs with approximate hits Top 50 customers per region with approximate spending
SELECT blog_post, APPROX_COUNT(*) SELECT region, customer_name,
FROM weblog APPROX_RANK(PARTITION BY region
GROUP BY blog_post ORDER BY APPROX_SUM(sales) DESC) appr_rank,
HAVING APPROX_SUM(sales) appr_sales
APPROX_RANK(order by FROM sales_transactions
APPROX_COUNT(*) DESC) <= 5; GROUP BY region, customer_name
HAVING APPROX_RANK(...) <=50;

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 102
Approximate Top-N vs Common Top-N 성능비교

Group by 및 sort 건수
3202 VS 4

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 103
Approximate(추정) 함수의 에러율은?

실제값과 추정치의 최대차이를 나타냄

건수를 늘려서 Test 함.


이 경우 실제 sum값과 차이가 없음으로 신뢰도
추정치와 실제값과 최대 차이는 10임. 따라서
100%임(건수가 작을 때는 차이가 없음)
매니저의 SUM(sal) 실제값은 11340~11350 사이임

추정치는 항상 과대평가됨

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 104
Approximate Top-N Queries
• Approx. functions:
– APPROX_COUNT, APPROX_SUM, APPROX_RANK
• 고성능
– 처리할 데이터가 클 수록 효율이 좋음
• 정확도가 높음
– Maximum error reporting : 최대 에러 값을 제시함
• "Top-N Structure" 는 Sort 일량을 줄임으로 메모리에서 처리될 가능성이 높음
– No disk sorts

Weblog Top-N
Read Structure Top-N
Data

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 105
세션은 취소하지 않은 상태에서 특정 SQL만 취소하라

4. ALTER SYSTEM CANCEL SQL

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


ALTER SYSTEM CANCEL SQL - KILL SESSION과 비교

특정 세션의 특정 SQL을 취소

특정 세션의 모든 SQL을 KILL

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 107
ALTER SYSTEM CANCEL SQL – 필요 스크립트
세션정보를 이용하여
SQL을 취소함

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | 108
Export/Import 재작업을 방지한다

5. Data Pump Enhancement

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Import with the CONTINUE_LOAD_ON_FORMAT_ERROR option
12c
IMPORT시 Stream format error가 발생되면, 로딩이 중단됨.
• 일반적으로 Stream format error는 손상된 dump 파일에서 발생됨
• Import되고있던 전체 데이터가 Rollback 됨
• 해결방법: 다시 export/import 함

Import를 2시간이나 기다렸는데


실패하다니 ㅠㅠ

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 110
Import with the CONTINUE_LOAD_ON_FORMAT_ERROR option

CONTINUE_LOAD_ON_FORMAT_ERROR option:
• 전체가 Rollback 되는 대신 에러가 발생한 데이터의 granule은 Skip됨.
• 다음 granule 부터 다시 Loading 시작하기 때문에 수백 ~ 수천행이 Skip될 수 있음
• Stream Format 에러가 없는 행을 찾아 데이터를 계속 로드 함
• Network Mode Import에서는 옵션이 무시됨(소스가 DB Link인 경우)

$ impdp hr TABLES = employees DUMPFILE = dpemp DIRECTORY = dirhr


DATA_OPTIONS = CONTINUE_LOAD_ON_FORMAT_ERROR

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 111
파티션 변경도 Online으로 가능하다

6. Online Partition Maintenance

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Online Partition and Subpartition Maintenance Operations
버전에 따른 Online Operation:
11g CREATE INDEX
ALTER TABLE ADD COLUMN
| ADD CONSTRAINT

12c DROP INDEX


ALTER INDEX UNUSABLE
ALTER TABLE DROP CONSTRAINT
| SET COLUMN UNUSED
| MOVE
| MOVE PARTITION
| SPLIT PARTITION
| MODIFY nonpartitioned to partitioned
| MOVE PARTITION INCLUDING ROWS

SQL> ALTER INDEX hr.i_emp_ix UNUSABLE ONLINE;


Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 113
Online Partition and Subpartition Maintenance Operations

Oracle 18는 아래와 같은 파티션 작업이 Online으로 가능하다 :

• ALTER TABLE MODIFY :repartitioning, add or remove subpartitioning


18c

• ALTER TABLE MERGE PARTITION


18c

SQL> ALTER TABLE sales MODIFY PARTITION BY RANGE (c1) INTERVAL (100)
(PARTITION p1 …, PARTITION p2 …) ONLINE UPDATE INDEXES;

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 114
Online Modification of Subpartitioning Strategy: Example
SQL> CREATE TABLE sales (prodno NUMBER NOT NULL, custno NUMBER, time_id DATE,
… qty_sold NUMBER(10,2), amt_sold NUMBER(10,2))
PARTITION BY RANGE (time_id)
(PARTITION s_q1_17 VALUES LESS THAN (TO_DATE('01-APR-2017','dd-MON-yyyy')),
PARTITION s_q2_17 VALUES LESS THAN (TO_DATE('01-JUL-2017','dd-MON-yyyy')), …);

SQL> CREATE INDEX i1_custno ON sales (custno) LOCAL;


SQL> CREATE UNIQUE INDEX i2_time_id ON sales (time_id);
SQL> CREATE INDEX i3_prodno ON sales (prodno);

SQL> ALTER TABLE sales MODIFY PARTITION BY RANGE (time_id)


SUBPARTITION BY HASH (custno) SUBPARTITIONS 8
(PARTITION s_q1_17 VALUES LESS THAN (TO_DATE('01-APR-2017','dd-MON-yyyy')),
PARTITION s_q2_17 VALUES LESS THAN (TO_DATE('01-JUL-2017','dd-MON-yyyy')), …)
ONLINE UPDATE INDEXES (i1_custno LOCAL, i2_time_id GLOBAL PARTITION BY
RANGE (time_id) ( PARTITION ip1 VALUES LESS THAN (MAXVALUE)));
• 위의 Modify Partition 구문은 Online 키워드가 있음으로 nonblocking 모드로 실행됨
• 1번 인덱스는 LOCAL로 지정되었음으로 Range-Hash Partitioning이 되고, 2번 인덱스는 Global Range Partitioning이 됨
• Update Indexes 절에 지정되지 않은 3번 인덱스의 경우 자동으로 Global Nonpartitioned Index가 됨
• 만약 지정되지 않은 인덱스의 첫번째 컬럼이 서브파티션 키(custno)와 같다면 자동으로 Local Partitioned Index가 됨

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 115
Online MERGE Partition and Subpartition: Example

SQL> CREATE TABLE sales


(prod_id NUMBER, cust_id NUMBER, time_id DATE, channel_id NUMBER,
promo_id NUMBER, quantity_sold NUMBER(10,2), amount_sold NUMBER(10,2))
PARTITION BY RANGE (time_id)
( PARTITION jan17 VALUES LESS THAN (TO_DATE('2017-02-01',‘YYYY-MM-DD')),
PARTITION feb17 VALUES LESS THAN (TO_DATE('2017-03-01',‘YYYY-MM-DD')),
PARTITION mar17 VALUES LESS THAN (TO_DATE('2017-04-01',‘YYYY-MM-DD')) );

SQL> CREATE INDEX i1_time_id ON sales (time_id) LOCAL TABLESPACE tbs_2;


SQL> CREATE INDEX i2_promo_id ON sales (promo_id) GLOBAL TABLESPACE tbs_2;

SQL> ALTER TABLE sales MERGE PARTITIONS jan17,feb17,mar17 INTO PARTITION q1_17
COMPRESS UPDATE INDEXES ONLINE;

서브파티션도 같은 방식으로
수행가능 함
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 116
PK INDEX의 Hot Block을 제거하라

7. Scalable Extend Sequence

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Scalable Extend Sequence - 시퀀스를 이용한 PK INDEX의 문제점
B-Tree 인덱스의
일반적인 모습

하위 블록이 없음

Hot Block: TRANSACTION이 집중되면


해결방법
12c

Index Split이 자주 발생됨.


Reverse Index? enq: TX - index contention
Hash Partitioned Index?
Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 118
Scalable Extend Sequence

Prefix 6자리가 생성됨


앞 3자리 : instance id
다음 3자리 : session id

1. No-Extend Scalable Sequence는 위험함


2. Maxvalue가 10자리임으로 prefix를 제외하면
9999까지만 사용할 수 있음
3. 4자리를 넘어갈 경우 아래와 같은 에러 발생

ORA-64603: NEXTVAL cannot be instantiated for SQ.


Widen the sequence by 1 digits or alter sequence with SCALE EXTEND.

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 119
Scalable Extend Sequence

Extend 키워드를 사용함으로 Maxvalue


까지 사용할 수 있음

따라서 SCALE 옵션을 사용한다면 반드시


Extend도 같이 사용할 것

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 120
Scalable Extend Sequence - enq: TX - index contention 문제가 줄어드는 이유

세션마다 Instance ID와


세션ID가 바뀜

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 121
PK 인덱스를 이용한 Table Access를 빠르게

8. Memoptimized Rowstore

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Memoptimized Rowstore
Memory Optimized Access for OLTP Workloads
• Ultra-Fast key-based lookup:
Example : Read Rays Balance
– In-memory hash index 구조
– Table을 MEMOPTIMIZE FOR READ로 선언
• Memoptimize Pool에 Hash Index와
Rowdata 저장
• 성능상 장점:
Look up of
Ray’s ID
(4004)
– Up to 4x throughput increase for Primary
Key based lookups
– 50% lower response times

Copyright © 2014 Oracle and/or its affiliates. All rights reserved.Oracle


| Confidential – Internal 123
Memoptimized Rowstore – 기존 방식과 비교

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 124
Memoptimized Rowstore – 적용(1/3)

1. memoptimize_pool_size 지정

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 125
Memoptimized Rowstore – 적용(2/3)

2. 테이블을 memoptimize for read로 지정

3. 데이터를 Memoptimized Rowstore에


Loading

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 126
Memoptimized Rowstore – 적용(3/3)

Alter Table 대신 테이블을 생성시


memoptimize for read로 지정 가능함

기능을 사용하지 않으려면


no memoptimize for read로 지정

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 127
Memoptimized Rowstore – 구조
Memoptimize 버퍼 영역:
• memoptimize 버퍼는 데이터베이스 버퍼 캐시와 동일한 구조를
사용함
• 하지만 버퍼캐시에 포함되지 않는 별개의 메모리 구조임
• memoptimize 버퍼 영역은 memoptimize 풀의 75 %를 차지함

Hash Index 영역
• 해시 인덱스를 여러 개의 인접하지 않은 메모리 Unit 에 할당함
• 각 유닛에는 많은 해시 버킷이 있음
• 해시 인덱스는 memoptimize 풀의 25 %를 차지함

두 가지 맵 구조로 메모리 유닛과 기본 키를 연관시킴

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 128
Memoptimized Rowstore – DBMS_MEMOPTIMIZE 패키지
Hash 인덱스 구조와 테이블(혹은 파티션)
data를 Memoptimize Pool에 Loading 함

Hash 인덱스 구조와 테이블(혹은 파티션)


data를 Memoptimize Pool에서 제거함

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 129
Memoptimized Rowstore - 주의 사항(1/2)

• 압축을 사용하면 Memoptimized Rowstore를 사용할 수 없음


• PK가 존재해야 하며, Where PK컬럼 = 조건에서만 사용가능
• PK 컬럼= 조건 이외의 조건이 있으면 사용할 수 없음

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 130
Memoptimized Rowstore - 주의 사항(2/2)

• 압축을 사용하면 Memoptimized Rowstore를 사용할 수 없음


• PK가 존재해야 하며, Where PK컬럼 = 조건에서만 사용가능
• PK 컬럼= 조건 이외의 조건이 있으면 사용할 수 없음

Copyright © 2018, Oracle and/or its affiliates. All rights reserved. 5 - 131
18c SQL을 실행하려면 LIVE SQL을 이용하라

Learn More 18c?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Learn More 18c? https://livesql.oracle.com

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 133
Learn More
18c?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 134
Learn More 18c?

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted 135
학습의 의미
學而時習之 不亦說乎
“배워서(學) 시간이 날 때마다 반복해(習) 몸에 익히면 진실로 기쁘지 않겠는가?”

학습 = 여러 번의 실습

공자(BC.551 ~ BC.479)

그림출처: 네이버 지식백과

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |


Safe Harbor Statement
The preceding is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.

Copyright © 2014 Oracle and/or its affiliates. All rights reserved. |

You might also like