-- 테이블 생성
CREATE TABLE CUSTOMER_XSOFT AS
SELECT ROWNUM CUSTOMER_ID,
DBMS_RANDOM.STRING('U', 10) CUSTOMER_NAME,
MOD(ROWNUM, 10) + 1 CUSTOMER_GRADE,
TO_CHAR(TO_DATE('20090101', 'YYYYMMDD') + (ROWNUM - 1), 'YYYYMMDD') JOIN_DATE
FROM DUAL
CONNECT BY LEVEL <= 1000
;
-- 통계정보 생성
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(USER,
'CUSTOMER_XSOFT',
CASCADE => TRUE);
END;
/
-- 실행계획
EXPLAIN PLAN FOR
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_ID,
CX.CUSTOMER_NAME,
CX.JOIN_DATE
FROM CUSTOMER_XSOFT CX
ORDER BY CUSTOMER_NAME
;
@xplan
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 24000 | 3 (34)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10001 | 1000 | 24000 | 3 (34)| 00:00:01 | Q1,01 | P->S | QC (ORDER) |
| 3 | SORT ORDER BY | | 1000 | 24000 | 3 (34)| 00:00:01 | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 1000 | 24000 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
| 5 | PX SEND RANGE | :TQ10000 | 1000 | 24000 | 2 (0)| 00:00:01 | Q1,00 | P->P | RANGE |
| 6 | PX BLOCK ITERATOR | | 1000 | 24000 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 7 | TABLE ACCESS FULL| CUSTOMER_XSOFT | 1000 | 24000 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------
14 rows selected.
SET SERVERTRACE OFF;
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_ID,
CX.CUSTOMER_NAME,
CX.JOIN_DATE
FROM CUSTOMER_XSOFT CX
ORDER BY CX.CUSTOMER_NAME
;
SELECT TQ_ID,
SERVER_TYPE,
PROCESS,
NUM_ROWS,
BYTES,
WAITS
FROM V$PQ_TQSTAT
ORDER BY DFO_NUMBER,
TQ_ID,
DECODE(SUBSTR(SERVER_TYPE, 1, 4), 'Rang', 1, 'Prod', 2, 'Cons', 3),
PROCESS
;
TQ_ID SERVER_TYPE PROCESS NUM_ROWS BYTES WAITS
----- ----------- ------- -------- ----- -----
0 Ranger QC 182 9808 1
0 Producer P002 548 14968 5
0 Producer P003 452 12427 3
0 Consumer P000 491 13421 88
0 Consumer P001 509 13908 89
1 Producer P000 491 13394 0
1 Producer P001 509 13881 0
1 Consumer QC 1000 27275 1
-- 그림 7_4 참조
EXPLAIN PLAN FOR
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_NAME,
COUNT(*)
FROM CUSTOMER_XSOFT CX
GROUP BY CUSTOMER_NAME
;
@xplan
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 11000 | 3 (34)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 1000 | 11000 | 3 (34)| 00:00:01 | Q1,01 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 1000 | 11000 | 3 (34)| 00:00:01 | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
| 5 | PX SEND HASH | :TQ10000 | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | P->P | HASH |
| 6 | PX BLOCK ITERATOR | | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 7 | TABLE ACCESS FULL| CUSTOMER_XSOFT | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------
14 rows selected.
EXPLAIN PLAN FOR
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_NAME,
COUNT(*)
FROM CUSTOMER_XSOFT CX
GROUP BY CX.CUSTOMER_NAME
ORDER BY CX.CUSTOMER_NAME
;
@xplan
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 11000 | 3 (34)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10001 | 1000 | 11000 | 3 (34)| 00:00:01 | Q1,01 | P->S | QC (ORDER) |
| 3 | SORT GROUP BY | | 1000 | 11000 | 3 (34)| 00:00:01 | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
| 5 | PX SEND RANGE | :TQ10000 | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | P->P | RANGE |
| 6 | PX BLOCK ITERATOR | | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 7 | TABLE ACCESS FULL| CUSTOMER_XSOFT | 1000 | 11000 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
-----------------------------------------------------------------------------------------------------------------------
14 rows selected.
SET AUTOTRACE OFF;
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_NAME,
COUNT(*)
FROM CUSTOMER_XSOFT CX
GROUP BY CX.CUSTOMER_NAME
ORDER BY CX.CUSTOMER_NAME
;
SELECT TQ_ID,
SERVER_TYPE,
PROCESS,
NUM_ROWS,
BYTES,
WAITS
FROM V$PQ_TQSTAT
ORDER BY DFO_NUMBER,
TQ_ID,
DECODE(SUBSTR(SERVER_TYPE, 1, 4), 'Rang', 1, 'Prod', 2, 'Cons', 3),
PROCESS
;
TQ_ID SERVER_TYPE PROCESS NUM_ROWS BYTES WAITS
----- ----------- ------- ---------- ---------- ----------
0 Ranger QC 182 4494 1
0 Producer P002 455 5616 4
0 Producer P003 545 6696 5
0 Consumer P000 491 6015 5760
0 Consumer P001 509 6231 5761
1 Producer P000 491 7976 0
1 Producer P001 509 8264 0
1 Consumer QC 1000 16240 3
EXPLAIN PLAN FOR
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_GRADE,
COUNT(*)
FROM CUSTOMER_XSOFT CX
GROUP BY CX.CUSTOMER_GRADE
;
@xplan
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 30 | 3 (34)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 10 | 30 | 3 (34)| 00:00:01 | Q1,01 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 10 | 30 | 3 (34)| 00:00:01 | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 10 | 30 | 3 (34)| 00:00:01 | Q1,01 | PCWP | |
| 5 | PX SEND HASH | :TQ10000 | 10 | 30 | 3 (34)| 00:00:01 | Q1,00 | P->P | HASH |
| 6 | HASH GROUP BY | | 10 | 30 | 3 (34)| 00:00:01 | Q1,00 | PCWP | |
| 7 | PX BLOCK ITERATOR | | 1000 | 3000 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 8 | TABLE ACCESS FULL| CUSTOMER_XSOFT | 1000 | 3000 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------------------------------
SELECT COLUMN_NAME,
NUM_DISTINCT,
NUM_NULLS,
1/NUM_DISTINCT SELECTIVITY,
ROUND(1/NUM_DISTINCT * T.NUM_ROWS, 2) CARDINALITY
FROM USER_TABLES T,
USER_TAB_COLUMNS C
WHERE T.TABLE_NAME = 'CUSTOMER_XSOFT'
AND C.TABLE_NAME = T.TABLE_NAME
ORDER BY COLUMN_ID
;
COLUMN_NAME NUM_DISTINCT NUM_NULLS SELECTIVITY CARDINALITY
-------------- ------------ ---------- ----------- -----------
CUSTOMER_ID 1000 0 .001 1
CUSTOMER_NAME 1000 0 .001 1
CUSTOMER_GRADE 10 0 .1 100
JOIN_DATE 1000 0 .001 1
SET AUTOTRACE OFF;
SELECT /*+ FULL(CX) PARALLEL(CX 2) */
CX.CUSTOMER_GRADE,
COUNT(*)
FROM CUSTOMER_XSOFT CX
GROUP BY CX.CUSTOMER_GRADE
;
SELECT TQ_ID,
SERVER_TYPE,
PROCESS,
NUM_ROWS,
BYTES,
WAITS
FROM V$PQ_TQSTAT
ORDER BY DFO_NUMBER,
TQ_ID,
DECODE(SUBSTR(SERVER_TYPE, 1, 4), 'Rang', 1, 'Prod', 2, 'Cons', 3),
PROCESS
;
TQ_ID SERVER_TYPE PROCESS NUM_ROWS BYTES WAITS
----- ----------- ------- ---------- ---------- ----------
0 Producer P002 10 208 0
0 Producer P003 10 208 0
0 Consumer P000 10 208 10
0 Consumer P001 10 208 10
1 Producer P000 5 64 1
1 Producer P001 5 64 2
1 Consumer QC 10 128 1