SELECT * FROM v$version
;
BANNER
------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit
PL/SQL Release 10.2.0.3.0 - Production
-- EMP, DEPT 테이블 생성
CREATE TABLE EMP
(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2));
INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, 0, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10);
CREATE TABLE DEPT
(DEPTNO NUMBER(2),
DNAME VARCHAR2(14),
LOC VARCHAR2(13) );
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
COMMIT;
/
CREATE UNIQUE INDEX EMP_U1 ON EMP (EMPNO);
CREATE INDEX EMP_N1 ON EMP (DEPTNO);
CREATE UNIQUE INDEX DEPT_U1 ON DEPT (DEPTNO);
CREATE INDEX DEPT_N1 ON DEPT (LOC);
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(USER,
'EMP',
CASCADE => TRUE);
END;
/
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(USER,
'DEPT',
CASCADE => TRUE);
END;
/
-- EMP 테이블 복제한 테이블 생성
CREATE TABLE T_EMP AS
SELECT *
FROM EMP,
(SELECT ROWNUM NO
FROM DUAL
CONNECT BY LEVEL <= 100000);
-- Hidden Parameter 현재 세팅된 값
SELECT A.KSPPINM NAME,
B.KSPPSTVL VALUE,
B.KSPPSTDF DEF_YN,
A.KSPPDESC DESCRIPTION
FROM X$KSPPI A,
X$KSPPSV B
WHERE A.INDX = B.INDX
AND LOWER(A.KSPPINM) IN (TRIM(LOWER('workarea_size_policy ')),
TRIM(LOWER('sort_area_size')))
ORDER BY 1
;
NAME VALUE DEF_YN DESCRIPTION
-------------------- ----- ------ ------------------------------------------------------
workarea_size_policy AUTO FALSE policy used to size SQL working areas (MANUAL/AUTO)
sort_area_size 65536 TRUE size of in-memory sort work area
;
-- workarea_size_policy 값 세션 레벨에서 변경
ALTER SESSION SET workarea_size_policy = MANUAL;
-- sort_area_size 값 세션 레벨에서 변경
ALTER SESSION SET sort_area_size = 1048576;
-- AutoTrace 테스트
SET autotrace traceonly;
SELECT *
FROM (SELECT NO,
EMPNO,
ENAME,
JOB,
MGR,
SAL,
AVG(SAL) OVER(PARTITION BY TO_CHAR(NO), DEPTNO) AVG_SAL
FROM T_EMP)
WHERE NO = 1
ORDER BY SAL DESC
;
Execution Plan
----------------------------------------------------------
Plan hash value: 2032858773
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1309K| 97M| | 67057 (1)| 00:13:25 |
| 1 | SORT ORDER BY | | 1309K| 97M| 240M| 67057 (1)| 00:13:25 |
|* 2 | VIEW | | 1309K| 97M| | 34817 (1)| 00:06:58 |
| 3 | WINDOW SORT | | 1309K| 97M| 240M| 34817 (1)| 00:06:58 |
| 4 | TABLE ACCESS FULL| T_EMP | 1309K| 97M| | 2576 (2)| 00:00:31 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("NO"=1)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
104 recursive calls
3958 db block gets
9399 consistent gets
80275 physical reads
0 redo size
893 bytes sent via SQL*Net to client
240 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
1 sorts (disk)
14 rows processed
;
-- Trace 결과
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.020 0.012 0 121 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 3 26.970 134.809 71180 9261 3958 14
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 5 26.990 134.821 71180 9382 3958 14
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user: APPS (ID=44)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
14 SORT ORDER BY (cr=9261 pr=71180 pw=71179 time=134808812 us)
14 VIEW (cr=9261 pr=71180 pw=71179 time=113696286 us)
1400000 WINDOW SORT (cr=9261 pr=71180 pw=71179 time=126296185 us)
1400000 TABLE ACCESS FULL T_EMP (cr=9255 pr=0 pw=0 time=106 us)
Wait Event Name Count Wait(sec) Max Wait
-------------------------------------------------- ------- ---------- --------
direct path write temp 13778 39.047 0.003
SQL*Net message to client 3 0.000 0.000
SQL*Net message from client 3 0.005 0.003
direct path read temp 57670 70.355 0.000
--------------------------------------------------- ------- --------- --------
Total 71454 109.41
;
SET autotrace traceonly;
SELECT /*+ ORDERED USE_MERGE(E) */
D.DEPTNO,
D.DNAME,
E.ENAME,
E.SAL,
E.JOB,
RANK() OVER(PARTITION BY D.DEPTNO ORDER BY E.SAL) SAL_RANK
FROM DEPT D,
EMP E
WHERE D.DEPTNO = E.DEPTNO
ORDER BY E.SAL DESC
;
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 1092 | 14 (29)| 00:00:01 |
| 1 | SORT ORDER BY | | 14 | 1092 | 14 (29)| 00:00:01 | --> UGA
| 2 | WINDOW SORT | | 14 | 1092 | 14 (29)| 00:00:01 | --> CGA
| 3 | MERGE JOIN | | 14 | 1092 | 12 (17)| 00:00:01 |
| 4 | SORT JOIN | | 4 | 116 | 6 (17)| 00:00:01 | --> CGA
| 5 | TABLE ACCESS FULL| DEPT | 4 | 116 | 5 (0)| 00:00:01 |
|* 6 | SORT JOIN | | 14 | 686 | 6 (17)| 00:00:01 | --> CGA
| 7 | TABLE ACCESS FULL| EMP | 14 | 686 | 5 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("D"."DEPTNO"="E"."DEPTNO")
filter("D"."DEPTNO"="E"."DEPTNO")
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
30 consistent gets
0 physical reads
0 redo size
925 bytes sent via SQL*Net to client
241 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
14 rows processed
;
1. DML 문장 수행 시 발생하는 소트는 CGA에서 수행
2. SELECT 문장 수행 시
1) 쿼리 중간 단계의 소트
① CGA에서 수행. sort_area_retained_size 제약이 있다면 다음 단계로 넘어가기 전에 이 값을 초과하는 CGA 영역을 반환
2) 결과집합을 출력하기 직전 단계에서 수행하는 소트
① sort_area_retained_size 제약이 있다면, CGA에서 소트 수행.
이 제약만큼의 UGA를 할당해 정렬된 결과를 담았다가 이후 Fetch Call에서 Array 단위로 전송
② sort_area_retained_size 제약이 없다면, 곧바로 UA에서 소트 수행