새로쓴 대용량 데이터베이스솔루션 1 (2008년)
병렬처리 관련 힌트 0 0 5,660

by 구루비 Hint 힌트 PARALLEL [2009.05.07]


3.3.5. 병렬처리 관련 힌트

병렬처리에 관련된 힌트들은 시스템 자원을 많이 사용하게 되므로 사용자의 요구에 따라 결정되어야 한다.
이런 유형의 힌트는 처리방법을 개선하여 일의 량을 줄이는 것이 아니라 시스템 자원을 최대한 사용하더라도 결과를 얻는 절대 시간을 줄이겠다는 것이 목적이다.
병렬처리는 시스템에 부하를 주더라도 수행시간을 당기는 것이더 필요할 때 적용하는 처리방법이다. 그러므로 가능하다면 기본값(Default value)을 사용하지 말고, SQL단위에서 힌트를 사용하여 적용하는것이 바람직하다.
병렬처리 힌트는 병렬처리에서 나타나는 병렬프로세스들의 개수를 지정하거나 내부처리방법에 대한 우리의 요구를 전달하기 위해 사용한다. 특히 병렬 프로세스의 개수는 수행시간 및 시스템의 부하에 직접적인 영향을 미치므로 매우 중요하다.

PARALLEL

대량의 데이터에 대한 테이블을 액세스 할 때와 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);

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)

문서에 대하여

  • 최초작성자 : 임주영
  • 최초작성일 : 2008년 3월 20일
  • 이 문서는 오라클클럽 대용량 데이터베이스 스터디 모임에서 작성하였습니다.
  • 이 문서의 내용은 이화식님의 새로쓴 대용량 데이터베이스 솔루션을 참고했습니다.
  • 이 문서를 다른 블로그나 홈페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^\^
"구루비 데이터베이스 스터디모임" 에서 2008년에 "새로쓴 대용량 데이터베이스 솔루션1" 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/2572

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입