문서의 이전 판입니다!
3.3.5. 병렬처리 관련 힌트
병렬처리에 관련된 힌트들은 시스템 자원을 많이 사용하게 되므로 사용자의 요구에 따라 결정되어야 한다.
본 유형의 HINT들은 시스템 자원을 최대한 사용하더라도 결과를 얻는 절대 시간을 줄이겠다는 것이 목적이다.즉 병렬처리는 시스템에 부하를 주더라도 수행시간을 당기는 것이 더 필요할 때 적용하는 처리방법이다. 그러므로 가능하다면 기본값(Default value)을 사용하지 말고, SQL단위에서 힌트를 사용하여 적용하는것이 바람직하다.
병렬처리 힌트는 병렬처리에서 나타나는 병렬프로세스들의 개수를 지정하거나 내부처리방법에 대한 우리의 요구를 전달하기 위해 사용한다. 특히 병렬 프로세스의 개수는 수행시간 및 시스템의 부하에 직접적인 영향을 미치므로 매우 중요하다.
PARALLEL
대량의 데이터에 대한 테이블을 액세스 할 때와 DML을 처리할 때 SQL의 병렬처리를 지시하는 힌트이다.
일반적으로 병렬 스레드(Parallel threads)를 나타내는 숫자와 함께 사용하고 있다.
만약 힌트에 병렬도(Parallel Degree)를 나타내는 숫자를 정의하지 않으면 옵티마이져는 PARALLEL_THREADS_PER_CPU 파라메터에 정의된 값을 자동으로 계산해서 적용한다.
만약 테이블 정의할 때 'PARALLEL'을 지정하였다면, 힌트를 사용하지 않아도 병렬처리가 가능한 경우에는 이 병렬도를 적용한다
병렬처리를 위하여 테이블/인덱스 생성시 미리 설정할 수 있다.
이때 CPU 기동수 입력시 실 CPU의 수보다 크게 적을 경우 단일 CPU 이용보다 느린 응답시간이 나올수 도 있다.
병렬처리시 최소한의 CPU 갯수는 3개임(2개는 쿼리수행, 1개는 퀴리 병합)
예) SQL>CREATE TABLE table1( code number(7), name varchar(20),...) parallel 20;
SQL>CREATE INDEX table1_index on table1(code) parallel 20;
DELETE, INSERT, UPDATE, MERGE등의 DML문장을 병렬로 수행하기 위해서는 반드시 세션을 'ALTER SESSION ENABLE PARALLEL DML'로 지정해야만 병렬처리가 가능하다.
참고: Parallel DML의 사용 설정
ALTER SESSION ENABLE | DISABLE [병렬 DML_statement]
: Enable되어 있는 상태에서의 병렬 DML의 실행 일지라도 Parallel Hint가 DML 내에 사용되지 않은경우 병렬처리 안됨
- ALTER SESSION FORCE [병렬 DML_statement] PARALLEL n
: 모든 DML 실행시 Parallel 힌트 사용여부나 PARALLEL 구문의 사용 여부에 개의치 않고 무조건 병렬처리됨
* 한 번 지정한 병렬도는 내부적으로 GROUP BY나 정렬처리 등의 단위작업에도 재차 적용될수 있다. 만약 병렬처리에 어떤 제한 요소가 발생하게 되면 이 힌트는 무시된다.
* 참고사항 : 보통 많은 책들에서 Update, Delete 시에 Partition TABLE이 아닌경우 PARALLEL 수행이 안된다고 하는데 실레로 10g에서 PARALLEL 수행이 된다고함 (관련링크 : http://scidb.tistory.com/6)
예) 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);
===NOPARALLEL===
*테이블을 정의 시에 PARALLEL옵션을 부여하면 쿼리에 직접 힌트를 주지 않아도 옵티마이져는 병렬처리가 가능하다고 판단되면 병렬처리 실행계획을 수립한다.
*SQL에 이 힌트를 적용하면 옵티마이져는 해당 테이블의 PARALLEL파라메터를 무시하고 병렬처리를 하지 않는 실행계획을 수립하게 된다.
예) SELECT /*+ NOPARALLEL(m) */ member_name
FROM member m;
===PQ_DISTRIBUTE===
병렬 조인의 속도를 향상시키기 위해 슬레이브 프로세스 - 생산자(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;
===PARALLEL_INDEX===
파티션 인덱스(Partitioned Index)에 대한 인덱스 범위 스캔을 병렬로 수행하기 위한 병렬도를 지정하는 힌트이다.
예) SELECT /*+ PARALLEL_INDEX(table1, index1, 3) */……….
===NOPARALLEL_INDEX===
인덱스 생성(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
[Oracle9iR2] (NOPARALLEL_INDEX)
[Oracle10gR2],11gR1 (NO_PARALLEL_INDEX)
==참조한문서==
“오라클클럽” http://wiki.oracleclub.com/pages/viewpage.action?pageId=1966261&