(on) Hints for Parallel Execution

PARALLELNO_PARALLEL
{code:sqltitleBGColor=#FFFFFFtitle=!http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/img/parallel_hint_object.gif!borderStyle=solid}
SELECT /*+ PARALLEL(T1 4) / N4, COUNT() FROM T1 GROUP BY N4;





























--

IdOperationNameRowsBytesCost (%CPU)TimeTQIN-OUTPQ Distrib





























--

0SELECT STATEMENT10304 (25)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ1000110304 (25)00:00:01Q1,01P->SQC (RAND)
3HASH GROUP BY10304 (25)00:00:01Q1,01PCWP
4PX RECEIVE10304 (25)00:00:01Q1,01PCWP
5PX SEND HASH:TQ1000010304 (25)00:00:01Q1,00P->PHASH
6HASH GROUP BY10304 (25)00:00:01Q1,00PCWP
7PX BLOCK ITERATOR10000300003 (0)00:00:01Q1,00PCWC
8TABLE ACCESS FULLT110000300003 (0)00:00:01Q1,00PCWP





























--

-- 시스템 자원을 많이 사용하게 되므로 필요할 때 쓰자
– PARALLEL DEGREE 를 지정하지 않으면 PARALLEL_THREADS_PER_CPU 값에 따라 자동 계산값 사용
– PARALLEL 속성을 가진 테이블은 힌트가 없어도 병렬처리 될 수 있음

|{code:sql|titleBGColor=#FFFFFF|title=!http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/img/no_parallel_hint.gif!|borderStyle=solid}
SELECT /*+ NO_PARALLEL(T1 4) */ N4, COUNT(*) FROM T1 GROUP BY N4;

-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    10 |    30 |     5   (0)| 00:00:01 |
|   1 |  SORT GROUP BY NOSORT|      |    10 |    30 |     5   (0)| 00:00:01 |
|   2 |   INDEX FULL SCAN    | T1N4 | 10000 | 30000 |     5   (0)| 00:00:01 |
-----------------------------------------------------------------------------

|

PARALLEL_INDEXNO_PARALLEL_INDEX
{code:sqltitleBGColor=#FFFFFFtitle=!http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/img/parallel_index_hint.gif!borderStyle=solid}
SELECT /*+ INDEX_FFS(T1) PARALLEL_INDEX(T1 T1N4 4) / N4, COUNT() FROM T1 GROUP BY N4;






























-

IdOperationNameRowsBytesCost (%CPU)TimeTQIN-OUTPQ Distrib






























-

0SELECT STATEMENT103012 (42)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ10001103012 (42)00:00:01Q1,01P->SQC (RAND)
3HASH GROUP BY103012 (42)00:00:01Q1,01PCWP
4PX RECEIVE103012 (42)00:00:01Q1,01PCWP
5PX SEND HASH:TQ10000103012 (42)00:00:01Q1,00P->PHASH
6HASH GROUP BY103012 (42)00:00:01Q1,00PCWP
7PX BLOCK ITERATOR10000300007 (0)00:00:01Q1,00PCWC
8INDEX FAST FULL SCANT1N410000300007 (0)00:00:01Q1,00PCWP






























-

– TQ : Table Queue
– QC : Query Coodinator
– S->P, P->S, P->P : Inter-Operation Parallelism
– PCWP, PCWC : Intra-Operation Parallelism

– TQ10000 : 생산자(Q1,00), 소비자(Q1,01)
– TQ10001 : 생산자(Q1,01), 소비자(QC)

|{code:sql|titleBGColor=#FFFFFF|title=!http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/img/no_parallel_index_hint.gif!|borderStyle=solid}
SELECT /*+ INDEX_FFS(T1) NO_PARALLEL_INDEX(T1 T1N4 4) */ N4, COUNT(*) FROM T1 GROUP BY N4;

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |    10 |    30 |     9  (23)| 00:00:01 |
|   1 |  HASH GROUP BY        |      |    10 |    30 |     9  (23)| 00:00:01 |
|   2 |   INDEX FAST FULL SCAN| T1N4 | 10000 | 30000 |     7   (0)| 00:00:01 |
------------------------------------------------------------------------------

|

PQ_DISTRIBUTE
{code:sqltitleBGColor=#FFFFFFtitle=!http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/img/pq_distribute_hint.gif!borderStyle=solid}
SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) */ * FROM PT1, PT2 WHERE PT1.N4 = PT2.N4;



































--

IdOperationNameRowsBytesCost (%CPU)TimePstartPstopTQIN-OUTPQ Distrib



































--

0SELECT STATEMENT10M1083M51 (61)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ1000110M1083M51 (61)00:00:01Q1,01P->SQC (RAND)
  • 3
HASH JOIN10M1083M51 (61)00:00:01Q1,01PCWP
4BUFFER SORTQ1,01PCWC
5PART JOIN FILTER CREATE:BF000010639540K18 (0)00:00:01Q1,01PCWP
6PX RECEIVE10639540K18 (0)00:00:01Q1,01PCWP
7PX SEND PARTITION (KEY):TQ1000010639540K18 (0)00:00:01S->PPART (KEY)
8PARTITION LIST ALL10639540K18 (0)00:00:01110
9TABLE ACCESS FULLPT110639540K18 (0)00:00:01110
10PX PARTITION LIST JOIN-FILTER10264521K2 (0)00:00:01:BF0000:BF0000Q1,01PCWC
11TABLE ACCESS FULLPT210264521K2 (0)00:00:01:BF0000:BF0000Q1,01PCWP



































--

Predicate Information (identified by operation id):













---

3 - access("PT1"."N4"="PT2"."N4")
– PT1, PT2 가 N4 컬럼으로 LIST 파티션 되어 있음
-- "PART JOIN FILTER CREATE, PX PARTITION LIST JOIN-FILTER" 발생 => PARTITION-WISE JOIN => PQ_DISTRIBUTE(PT2 NONE NONE) 와 같은 결과

SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) PQ_DISTRIBUTE(PT2 HASH HASH) */ * FROM PT1, PT2 WHERE PT1.N4 = PT2.N4;


































-

IdOperationNameRowsBytesCost (%CPU)Ti
me
PstartPstopTQIN-OUTPQ Distrib


































-

0SELECT STATEMENT10M1083M51 (61)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ1000210M1083M51 (61)00:00:01Q1,02P->SQC (RAND)
  • 3
HASH JOIN BUFFERED10M1083M51 (61)00:00:01Q1,02PCWP
4BUFFER SORTQ1,02PCWC
5PART JOIN FILTER CREATE:BF000010639540K18 (0)00:00:01Q1,02PCWP
6PX RECEIVE10639540K18 (0)00:00:01Q1,02PCWP
7PX SEND HASH:TQ1000010639540K18 (0)00:00:01S->PHASH
8PARTITION LIST ALL10639540K18 (0)00:00:01110
9TABLE ACCESS FULLPT110639540K18 (0)00:00:01110
10PX RECEIVE10264521K2 (0)00:00:01Q1,02PCWP
11PX SEND HASH:TQ1000110264521K2 (0)00:00:01Q1,01P->PHASH
12PX BLOCK ITERATOR10264521K2 (0)00:00:01:BF0000:BF0000Q1,01PCWC
13TABLE ACCESS FULLPT210264521K2 (0)00:00:01:BF0000:BF0000Q1,01PCWP


































-

Predicate Information (identified by operation id):













---

3 - access("PT1"."N4"="PT2"."N4")
-- 위와 같은 쿼리에 억지로 HASH 분배 적용

SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) */ * FROM PT1, PT2 WHERE PT1.N2 = PT2.N2;

































--

IdOperationNameRowsBytesCost (%CPU)TimePstartPstopTQIN-OUTPQ Distrib

































--

0SELECT STATEMENT113K11M21 (5)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ10002113K11M21 (5)00:00:01Q1,02P->SQC (RAND)
  • 3
HASH JOIN BUFFERED113K11M21 (5)00:00:01Q1,02PCWP
4BUFFER SORTQ1,02PCWC
5PX RECEIVE10639540K18 (0)00:00:01Q1,02PCWP
6PX SEND HASH:TQ1000010639540K18 (0)00:00:01S->PHASH
7PARTITION LIST ALL10639540K18 (0)00:00:01110
8TABLE ACCESS FULLPT110639540K18 (0)00:00:01110
9PX RECEIVE10264521K2 (0)00:00:01Q1,02PCWP
10PX SEND HASH:TQ1000110264521K2 (0)00:00:01Q1,01P->PHASH
11PX BLOCK ITERATOR10264521K2 (0)00:00:01110Q1,01PCWC
12TABLE ACCESS FULLPT210264521K2 (0)00:00:01110Q1,01PCWP

































--

Predicate Information (identified by operation id):













---

3 - access("PT1"."N2"="PT2"."N2")
-- 파티션 되지 않은 컬럼(N2) 로 조인 하면 HASH 분배 발생

SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) PQ_DISTRIBUTE(PT2 BROADCAST NONE) */ * FROM PT1, PT2 WHERE PT1.N2 = PT2.N2;

































--

IdOperationNameRowsBytesCost (%CPU)TimePstartPstopTQIN-OUTPQ Distrib

































--

0SELECT STATEMENT113K11M21 (5)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ10001113K11M21 (5)00:00:01Q1,01P->SQC (RAND)
  • 3
HASH JOIN113K11M21 (5)00:00:01Q1,01PCWP
4BUFFER SORTQ1,01PCWC
5PX RECEIVE10639540K18 (0)00:00:01Q1,01PCWP
6PX SEND BROADCAST:TQ1000010639540K18 (0)00:00:01S->PBROADCAST
7PARTITION LIST ALL10639540K18 (0)00:00:01110
8TABLE ACCESS FULLPT110639540K18 (0)00:00:01110
9PX BLOCK ITERATOR10264521K2 (0)00:00:01110Q1,01PCWC
10TABLE ACCESS FULLPT210264521K2 (0)00:00:01110Q1,01PCWP

































--

Predicate Information (identified by operation id):













---

3 - access("PT1"."N2"="PT2"."N2")
-- 위와 같은 쿼리에 PT1을 억지로 BROADCAST 분배 적용 (비효율)

SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) */ * FROM PT1, PT2 WHERE PT1.N3 = PT2.N1 AND PT1.N1 = 0;

































--

IdOperationNameRowsBytesCost (%CPU)TimePstartPstopTQIN-OUTPQ Distrib

































--

0SELECT STATEMENT110424 (5)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ10001110424 (5)00:00:01Q1,01P->SQC (RAND)
  • 3
HASH JOIN110424 (5)00:00:01Q1,01PCWP
4BUFFER SORTQ1,01PCWC
5PX RECEIVE15218 (0)00:00:01Q1,01PCWP
6PX SEND BROADCAST:TQ1000015218 (0)00:00:01S->PBROADCAST
7PARTITION LIST ALL15218 (0)00:00:01110
  • 8
TABLE ACCESS FULLPT115218 (0)00:00:01110
9PX BLOCK ITERATOR10264521K5 (0)00:00:01110Q1,01PCWC
  • 10
TABLE ACCESS FULLPT210264521K5 (0)00:00:01110Q1,01PCWP

































--

Predicate Information (identified by operation id):













---

3 - access("PT1"."N3"="PT2"."N1")
8 - filter("PT1"."N1"=0)
10 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"PT2"."N1"))
-- 위와 같은 쿼리에 PT1 쪽이 작으므로 자연스럽게 PT1 의 BROADCAST 발생

SELECT /*+ USE_HASH(PT1, PT2) ORDERED PARALLEL(PT2 4) */ * FROM PT2, PT1 WHERE PT1.N3 = PT2.N1 AND PT1.N1 = 0;

































--

IdOperationNameRowsBytesCost (%CPU)TimePstartPstopTQIN-OUTPQ Distrib

































--

0SELECT STATEMENT110424 (5)00:00:01
1PX COORDINATOR
2PX SEND QC (RANDOM):TQ10001110424 (5)00:00:01Q1,01P->SQC (RAND)
  • 3
HASH JOIN110424 (5)00:00:01Q1,01PCWP
4PX BLOCK ITERATOR10264521K5 (0)00:00:01110Q1,01PCWC
5TABLE ACCESS FULLPT210264521K5 (0)00:00:01110Q1,01PCWP
6BUFFER SORTQ1,01PCWC
7PX RECEIVE15218 (0)00:00:01Q1,01PCWP
8PX SEND BROADCAST:TQ1000015218 (0)00:00:01S->PBROADCAST
9PARTITION LIST ALL15218 (0)00:00:01110
  • 10
TABLE ACCESS FULLPT115218 (0)00:00:01110

































--

Predicate Information (identified by operation id):













---

3 - access("PT1"."N3"="PT2"."N1")
10 - filter("PT1"."N1"=0)
-- 위와 같은 쿼리에 조인 순서를 바꾼결과 역시 PT1 쪽이 작으므로 자연스럽게 PT1 의 BROADCAST 발생

http://121.254.172.39:8080/pls/apex/f?p=101:11:0::::P11_QUESTION_ID:6418000346262286
http://download.oracle.com/docs/cd/E11882_01/server.112/e10837/parallel002.htm

-- 생산자(Producer) 와 소비자(Consumer) 프로세스 사이에서 조인할 테이블 로우를 주고 받는 할당 작업(Distribution) 방법 정의
-- 표현형식 : /*+ PQ_DISTRUBUTE(table, outer_distribution, inner_distribution) */
-- * HASH : 조인 키 컬럼에 대해 해쉬 함수 결과 값을 이용하여 분배
-- * BROADCAST : 외측 테이블의 전체 로우를 모든 Consumer 프로세스로 보냄
-- * PARTITION : 상대편 조인 대상 테이블이 조인 키 컬럼으로 파티션되어 있는 경우 파티션 키 값을 이용
-- * NONE : ...

-- 가능한 COMBINATION
– HASH - HASH : OUTER, INNER 크기가 비슷할 때
– BROADCAST - NONE : OUTER 테이블이 작을때
– NONE - BROADCAST : INNER 테이블이 작을때
– PARTITION - NONE : OUTER 테이블을 파티션 하여 분배
– NONE - PARTITION : INNER 테이블을 파티션 하여 분배
– NONE - NONE : 조인컬럼 기준으로 파티션 되어 있을때

|