본문 바로가기

IT관련

병렬처리, Parallel Join 에서 /*+ pq_distribute(,,) */ 힌트

/*+ pq_distribute */ 힌트는 오라클DB에서 Parallel Join 시에 사용할 수 있는 힌트입니다.

두 테이블 이상 조인하는 SQL문에서 /*+ parallel(8) */ 힌트를 주게되면 병렬프로세스간에 조인이 발생합니다.

 

이때 조인하는 방식이 여러가지가 있습니다.

 

한쪽 테이블의  데이터를 모든 병렬서버들에게 전달하는 브로드캐스트(broadcast) 방식,

양쪽 테이블 데이터에 해시함수를 적용해서 해시값을 구한후 이것들을 가지고 조인하는 방식,

조인되는 테이블이 파티션 되어있는 경우 파티션 Wise Join 을 하는 방식.

 

 

이런식으로 옵티마이저(Optimizer)가 여건에 따라 선택할 수 있는 몇가지 조인옵션이 있습니다.

물론 위 중에서 어떤 것을 선택할지는 옵티마이저가 알아서 판단해서 결정합니다.

하지만, 꼭 옵티말한 선택을 하지는 않는다는 함정이 있죠~ ㅎㅎ

 

그래서 옵티마이저한테 요런식으로 하라고 가이드할 수 있는 힌트가 있습니다.

바로 /*+ pq_distribute */ 힌트입니다.

 

 


SQL>
select /*+ parallel(8) leading(tab1) pq_distribute(tab2, hash, hash) */ ...
from tab1, tab2
where tab1.aaa = tab2.aaa
;

 

 

pq_distribute 힌트 포맷은 다음과 같습니다.

 

   /*+ pq_distribute(inner_table, outer_distribution, inner_distribution) */

 

 

두 테이블이 조인할 때, 리딩하는 테이블을 Driving Table 또는 Outer Table 이라고 합니다.

Outer Table 과 조인되어지는 테이블을 Inner Table 이라고 합니다.

위 SQL문에서는 leading(tab1) 힌트를 줬기 때문에 tab1 테이블이 Outer Table 이 되어 먼저 읽어지고,

tab2 테이블이 Inner Table 이 됩니다.

 

여기에 한가지 더, 병렬처리(Parallel Processing) 에서는 Producer, Consumer 라는 개념이 있습니다.

조인하지 않고 한 테이블에서 데이터를 읽어서 처리하는 경우에도 병렬처리시에는 2쌍의 병렬프로세서들이 일을 나누어서 합니다.

테이블에서 데이터를 읽는 역할을 하는 애들은 "Producer 병렬서버"라고 하고,

읽은 데이터를 Sort, DML 등의 작업을 하는 애들은 "Consumer 병렬서버"라고 합니다. 

 

 

pq_distribute 힌트에서 지정하는 옵션에 따라 아래와 같이 6가지가 있습니다.

 

 

* pq_distribute(tab2, hash, hash)


병렬조인을 위해 해시함수를 사용하도록 지정.
테이블에서 병렬로 읽은 데이터들을 Producer 병렬서버들로부터 Consumer 병렬서버들에게로 전달할때 해시함수를 사용.
>> 병렬조인에서 hash join 또는 sort merge join 을 하면서 조인하는 테이블들이 꽤 큰 경우에 이 방식을 사용하는게 좋습니다.


* pq_distribute(tab2, broadcast, none)


Outer 테이블의 모든 데이터들을 병렬서버들에게 브로드캐스트(쫙 뿌림).
Inner 테이블의 데이터들은 랜덤하게 파티션됨.
>> Outer 테이블이 심하게 작을때 사용.


* pq_distribute(tab2, none, broadcast)


Inner 테이블의 모든 데이터들을 각각의 Consumer 병렬서버들에게 브로드캐스트(쫙 뿌림).
Outer 테이블의 데이터들은 랜덤하게 파티션됨.
>> Inner 테이블이 심하게 작을때 사용.


* pq_distribute(tab2, partition, none)


Inner 테이블의 파티셔닝을 사용해서 Outer 테이블의 데이터를 매핑. (부분적인 Partition-wise Join)
Outer 테이블을 Inner 테이블에 매핑할때 Outer 테이블을 Inner 테이블의 파티션키에 맞추어 내부적으로 파티셔닝하는 것.
따라서 Inner 테이블은 Join Key 컬럼으로 파티션되어 있어야 함. (Inner 테이블이 파티션되어 있지 않은 경우에는 사용 못함)
>> Inner 테이블의 파티션 갯수가 병렬프로세스 수와 같은 경우에 사용하면 좋음.


* pq_distribute(tab2, none, partition)


Outer 테이블의 파티셔닝을 사용해서 Inner 테이블의 데이터를 매핑. (부분적인 Partition-wise Join)
Outer 테이블을 Inner 테이블에 매핑할때 Inner 테이블을 Outer 테이블의 파티션키에 맞추어 내부적으로 파티셔닝하는 것.
따라서 Outer 테이블은 Join Key 컬럼으로 파티션되어 있어야 함. (Outer 테이블이 파티션되어 있지 않은 경우에는 사용 못함)
>> Outer 테이블의 파티션 갯수가 병렬프로세스 수와 같은 경우에 사용하면 좋음.


* pq_distribute(tab2, none, none)


Outer, Inner 테이블간의 매칭되는 파티션끼리 조인작업을 수행. (Full Partition-wise Join)
Outer, Inner 테이블 모두 Join Key 컬럼으로 파티션되어 있어야 함. 
>> Outer, Inner 테이블 모두 Join Key 컬럼으로 파티션되어 있는 경우에 사용.

 

 

 

참고 ▶▶ 오라클 파티션 종합 페이지

참고 ▶ 오라클 병렬처리 종합페이지