병렬처리
병렬처리 수행 과정 및 QC의 역할
1. 병렬 SQL이 시작되면 QC는 사용자가 지정한 병렬도(DOP, Degree Of Parallelism)와 오퍼레이션 종류에 따라 하나 또는 두개의 병렬 서버집합(Server Set)을 할당한다. 우선 서버풀(Parallel Execution Server Pool)로부터 필요한 만큼 서버 프로세스를 확보하고, 부족분은 새로 생성한다.
2. QC는 각 병렬서버에게 작업을 할당한다. 작업을 지시하고 일이 잘 진행되는지 관리,감독하는 작업반장의 역할이다.
3. 병렬로 처리하도록 사용자가 지시하지 않은 테이블은 QC가 직접 처리한다. 예를 들어, 아래와 같은 실행계획에서 dept테이블을 직렬로 읽어 병렬서버에 전송하는 8~9번 오퍼레이션은 QC의 몫이다.
4. QC는 각 병렬서버로부터의 산출물을 통합하는 작업을 수행한다. 예를 들어 집계함수(sum, avg, min, max 등)가 사용된 아래와 같은 병렬쿼리를 수행할 때, 각 병렬서버가 자신의 처리범위 내에서 집계(4번 단계)한 값을 QC에게 전송(3번 단계)하면 QC가 최종 집계 작업을 수행(1번 단계)한다.
5. QC는 쿼리의 최종 결과집합을 사용자에게 전송하며, DML일때는 갱신건수를 집계해서 전송해 준다. 쿼리결과를 전송하는 단계에서 수행되는 스칼라서브쿼리도 QC가 수행한다.
병렬처리 실행 예제
SET AUTOT ON
SELECT /*+ ordered use_hash(d) full(d) full(e) noparallel(d) parallel(e 4) */
COUNT(*)
, MIN(sal)
, MAX(sal)
, AVG(sal)
, SUM(sal)
FROM dept d, emp e
WHERE d.loc = 'CHICAGO'
AND e.deptno = d.deptno
;
Execution Plan
----------------------------------------------------------
Plan hash value: 321505112
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 47 | 6 (17)| 00:00:01 | | | |
| 1 | SORT AGGREGATE | | 1 | 47 | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | 47 | | | Q1,02 | P->S | QC (RAND) |
| 4 | SORT AGGREGATE | | 1 | 47 | | | Q1,02 | PCWP | |
|* 5 | HASH JOIN | | 5 | 235 | 6 (17)| 00:00:01 | Q1,02 | PCWP | |
| 6 | BUFFER SORT | | | | | | Q1,02 | PCWC | |
| 7 | PX RECEIVE | | 1 | 21 | 3 (0)| 00:00:01 | Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | 1 | 21 | 3 (0)| 00:00:01 | | S->P | HASH |
|* 9 | TABLE ACCESS FULL| DEPT | 1 | 21 | 3 (0)| 00:00:01 | | | |
| 10 | PX RECEIVE | | 14 | 364 | 2 (0)| 00:00:01 | Q1,02 | PCWP | |
| 11 | PX SEND HASH | :TQ10001 | 14 | 364 | 2 (0)| 00:00:01 | Q1,01 | P->P | HASH |
| 12 | PX BLOCK ITERATOR | | 14 | 364 | 2 (0)| 00:00:01 | Q1,01 | PCWC | |
| 13 | TABLE ACCESS FULL| EMP | 14 | 364 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("E"."DEPTNO"="D"."DEPTNO")
9 - filter("D"."LOC"='CHICAGO')
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
24 recursive calls
0 db block gets
8 consistent gets
0 physical reads
0 redo size
390 bytes sent via SQL*Net to client
239 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
Order By를 포함하는 병렬처리 실행 예제
SELECT /*+ full(고객) parallel(고객 4) */ *
FROM 고객
ORDER BY 고객명
;
그림 | DOP(병렬도) | p(병렬프로세스) | :TQ10000(S->P) | :TQ10001(P->P) | :TQ10002(P->S) |
---|---|---|---|---|---|
7-1 | 4 | 4 | 4 | 0 | 4 |
7-2 | 4 | 8(4*2) | 4 | 16(4^2) | 4 |
7-3 | 2 | 4(2*2) | 2 | 4(2^2) | 2 |
Order By 병렬처리 실행 예제
SELECT /*+ ordered use_hash(e) full(d) noparallel(d) full(e) parallel(e 2) pq_distribute(e broadcast none) */ *
FROM dept d, emp e
WHERE e.deptno = d.deptno
ORDER BY e.ename
;
Execution Plan
----------------------------------------------------------
Plan hash value: 709482007
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 1638 | 7 (29)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10002 | 14 | 1638 | 7 (29)| 00:00:01 | Q1,02 | P->S | QC (ORDER) |
| 3 | SORT ORDER BY | | 14 | 1638 | 7 (29)| 00:00:01 | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 14 | 1638 | 6 (17)| 00:00:01 | Q1,02 | PCWP | |
| 5 | PX SEND RANGE | :TQ10001 | 14 | 1638 | 6 (17)| 00:00:01 | Q1,01 | P->P | RANGE |
|* 6 | HASH JOIN | | 14 | 1638 | 6 (17)| 00:00:01 | Q1,01 | PCWP | |
| 7 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 8 | PX RECEIVE | | 4 | 120 | 3 (0)| 00:00:01 | Q1,01 | PCWP | |
| 9 | PX SEND BROADCAST | :TQ10000 | 4 | 120 | 3 (0)| 00:00:01 | | S->P | BROADCAST |
| 10 | TABLE ACCESS FULL| DEPT | 4 | 120 | 3 (0)| 00:00:01 | | | |
| 11 | PX BLOCK ITERATOR | | 14 | 1218 | 2 (0)| 00:00:01 | Q1,01 | PCWC | |
| 12 | TABLE ACCESS FULL | EMP | 14 | 1218 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
--------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("E"."DEPTNO"="D"."DEPTNO")
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
191 recursive calls
3 db block gets
40 consistent gets
0 physical reads
632 redo size
1295 bytes sent via SQL*Net to client
239 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
8 sorts (memory)
0 sorts (disk)
14 rows processed
구분 | 명칭 | 설명 | (Intra/Inter)-Operation Parallelism | 오퍼레이션 |
---|---|---|---|---|
S->P | PARALLEL_FROM_SERIAL | QC가 읽은 데이터를 테이블 큐를 통해 병렬서버 프로세스에게 전송 | X | 직렬 |
P->S | PARALLEL_TO_SERIAL | 각 병렬서버 프로세스가 처리한 데이터를 QC에게 전송 | Inter | 병렬 |
P->P | PARALLEL_TO_PARALLEL | 데이터를 재분배(redistribution)하는 오퍼레이션 데이터를 정렬 또는 그룹핑하거나 조인을 위해 동적으로 파티셔닝할 때 사용 | Inter | 병렬 |
PCWP | PARALLEL_COMBINED_WITH_PARENT | 한 서버집합이 현재스텝과 부모스텝을 모두 처리 | Intra | 병렬 |
PCWC | PARALLEL_COMBINED_WITH_CHILD | 한 서버집합이 현재스텝과 자식스텝을 모두 처리 | Intra | 병렬 |
SERIAL | 공백인 경우 SERIAL 방식으로 처리 | X | 직렬 |
구분 | 내용 |
---|---|
RANGE | Order By 또는 Group By 를 병렬로 처리할 때 사용 정렬작업을 맡은 두번째 서버집합의 프로세스마다 처리범위를 지정하고 나서 데이터를 읽는 첫번째 서버집합이 정렬키값에 따라 정해진 범위에 해당하는 두번째 프로세스에게 분배하는 방식 QC는 작업범위를 할당하며, 정렬작업에는 참여하지 않는다. 정렬결과를 순서대로 받아서 사용자에게 전송하는 역할만 담당 |
HASH | 조인이나 Hash Group By 를 병렬로 처리할 때 사용 조인 키나 Group By 키값을 해시함수에 적용하여 리턴되는 값에 따라 데이터를 분배 P->P 뿐만 아니라 S->P 방식으로 이루어 질수도 있다. |
BROADCAST | QC 또는 첫번째 서버집합의 프로세스들이 각각 읽은 데이터를 두번째 서버집합의 "모든" 병렬프로세스에게 전송하는 방식 병렬 조인에서 크기가 매우 작은 테이블이 있을 때 사용되며 P->P 뿐만 아니라 S->P 방식으로 이루어 진다. 작은 테이블은 병렬로 읽지 않을 때가 많으므로 오히려 S->P가 일반적임 |
KEY | 특정 컬럼(들)을 기준으로 테이블 또는 인덱스를 파티셔닝할때 사용하는 분배 방식 실행계획에는 'PARTITION (KEY)'로 표시된다.(줄여서 'PART (KEY)'). |
ROUND-ROBIN | 파티션키, 정렬키, 해시함수에 의존하지 않고 반대편 정렬 서버에 무작위로 데이터 분배 골고루 분배되도록 ROUND-ROBIN 방식 사용 |