병렬처리에 관련된 힌트들은 시스템 자원을 많이 사용하게 되므로 사용자의 요구에 따라 결정되어야 한다.
이런 유형의 힌트는 처리방법을 개선하여 일의 량을 줄이는 것이 아니라 시스템 자원을 최대한 사용하더라도 결과를 얻는 절대 시간을 줄이겠다는 것이 목적이다.
병렬처리는 시스템에 부하를 주더라도 수행시간을 당기는 것이더 필요할 때 적용하는 처리방법이다. 그러므로 가능하다면 기본값(Default value)을 사용하지 말고, SQL단위에서 힌트를 사용하여 적용하는것이 바람직하다.
병렬처리 힌트는 병렬처리에서 나타나는 병렬프로세스들의 개수를 지정하거나 내부처리방법에 대한 우리의 요구를 전달하기 위해 사용한다. 특히 병렬 프로세스의 개수는 수행시간 및 시스템의 부하에 직접적인 영향을 미치므로 매우 중요하다.
대량의 데이터에 대한 테이블을 액세스 할 때와 DML을 처리할 때 SQL의 병렬처리를 지시하는 힌트이다. 일반적으로 병렬 스레드(Parallel threads)를 나타내는 숫자와 함께 사용하고 있다.
만약 힌트에 병렬도(Parallel Degree)를 나타내는 숫자를 정의하지 않으면 옵티마이져는 PARALLEL_THREADS_PER_CPU 파라메터에 정의된 값을 자동으로 계산해서 적용한다.
만약 테이블 정의할 때 'PARALLEL'을 지정하였다면, 힌트를 사용하지 않아도 병렬처리가 가능한 경우에는 이 병렬도를 적용한다. 그러나 DELETE, INSERT, UPDATE, MERGE등의 DML문장을 병렬로 수행하기 위해서는 반드시 세션을 'ALTER SESSION ENABLE PARALLEL DML'로 지정해야만 병렬처리가 가능하다. 한 번 지정한 병렬도는 내부적으로 GROUP BY나 정렬처리 등의 단위작업에도 재차 적용될수 있다. 만약 병렬처리에 어떤 제한 요소가 발생하게 되면 이 힌트는 무시된다.
예) SELECT /*+ FULL(sales) PARALLEL(sales) */
SUBSTR(sale_dt,1,6), SUM(qty)
FROM sales
WHERE sale_dt BETWEEN '20030101' AND '20051231'
GROUP BY SUBSTR(sale_dt,1,6);
SELECT /*+ FULL(sales) PARALLEL(sales, 8) */
SUBSTR(sale_dt,1,6), SUM(qty)
FROM sales
WHERE sale_dt BETWEEN '20030101' AND '20051231'
GROUP BY SUBSTR(sale_dt,1,6);
테이블을 정의 시에 PARALLEL옵션을 부여하면 쿼리에 직접 힌트를 주지 않아도 옵티마이져는 병렬처리가 가능하다고 판단되면 병렬처리 실행계획을 수립한다. 이때 SQL에 이 힌트를 적용하면 옵티마이져는 해당 테이블의 PARALLEL파라메터를 무시하고 병렬처리를 하지 않는 실행계획을 수립하게 된다.
예) SELECT /*+ NOPARALLEL(m) */ member_name
FROM member m;
병렬 조인의 속도를 향상시키기 위해 슬레이브 프로세스 - 생산자(Producer)와 소비자(Consumer)프로세스 - 사이에서 조인할 테이블의 로우를 서로 주고 받는 할당작업(Distrubution)을 하는 방법을 정의 하는 힌트이다.
표현 방식: /*+ PQ_DISTRIBUTE(table, outer_distribution,inner_distribution) */ - outer_distribution: 외측 테이블에 대한 할당 방법을 기술 - inner_distribution: 내측 테이블에 대한 할당 방법을 기술 - 할당방법: * HASH: 조인 키 컬럼에 대해 해쉬 함수를 수행한 결과값을 이용하여 소비자 프로세스에 로우들을 할당 * BROADCAST: 외측 테이블에 전체 로우를 모든 Consumer 프로세스로 보냄 * PARTITON: 상대편 조인 대사 테이블이 조인 키 컬럼으로 파티션되어 있는 경우 파티션 키 값을 이용하여 로우들을 Consumer프로세스에 할당 * NONE: 조인 대상 로우들을 랜덤하게 파티셔닝함
예) SELECT /*+ ORDERED PQ_DISTRIBUTE(b HASH,HASH) USE_HASH(b) */.....
FROM TAB1 a, TAB2 b
WHERE a.col1 = b.col2;
SELECT /*+ PQ_DISTRIBUTE(b BROADCAST, NONE) USE_HASH(b) */..........
FROM TAB1 a, TAB2 b
WHERE a.col1 = b.col2;
파티션 인덱스(Partitioned Index)에 대한 인덱스 범위 스캔을 병렬로 수행하기 위한 병렬도를 지정하는 힌트이다.
예) SELECT /*+ PARALLEL_INDEX(table1, index1, 3) */..........
인덱스 생성(Create)이나 변경(Alter)에 의해 PARALLEL 파라메터가 적용되어 있는 경우 SQL에서 이 힌트를 적용하면 옵티마이져는 해당 인덱스에 대한 PARALLEL 파라메터를 무시하여 범위스캔을 하지 않게 된다.
예) SELECT /*+ NOPARALLEL_INDEX(m mem_join_idx) */....
FROM members m
WHERE join_date BETWEEN '20040101' AND '20051231';
NOPARALLEL_INDEX힌트는 버전에 따라 NO_PARALLEL_INDEX힌트로 대체되어 사용되기도 한다.
Oracle버전별 NOPARALLEL_INDEX Hint