DATOR


Program Parallel 방식의 진화 DBMS_PARALLEL_EXECUTE (3)


 

1. DBMS_PARALLEL_EXECUTE 개념과 ROWID 배분방식 사례

2. 작업 단위(Chunk) 균일성, 누락없음 확인

3. NUMBER Column 배분방식 사례

4. 사용자 정의 SQL 배분방식 사례(DB Link를 통한 ROWID 배분)

5. Serial 성능 비교

6. 모니터링과 오류 처리, 주의사항

 

이번 글에서는 NUMBER Column에 의한 배분방식의 사례를 살펴보자.

ROWID 방식과 거의 유사한데, 다음 항목만 조금 다르다.

  • 작업 단위 분할시에 CREATE_CHUNKS_BY_NUMBER_COL procedure를 사용
  • 작업 실행시 SQL StatementWHERE절에 NUMBER column을 사용

 

----------------------------------------------------------------------------------------------------
-- 1
단계: 작업생성

BEGIN
  DBMS_PARALLEL_EXECUTE.CREATE_TASK(TASK_NAME => 'DPE_TEST(BY NUMBER)'
);
END;
/


--
작업 생성 확인
SELECT * FROM  USER_PARALLEL_EXECUTE_TASKS WHERE TASK_NAME = 'DPE_TEST(BY NUMBER)';

 

----------------------------------------------------------------------------------------------------
-- 2단계: 작업 단위 분할
BEGIN
  DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_NUMBER_COL
(
            TASK_NAME   
=> 'DPE_TEST(BY NUMBER)',
            TABLE_OWNER 
=> USER,
            TABLE_NAME  
=> 'Z_DPE_TEST_TAB',
            TABLE_COLUMN
=> 'ID',
            CHUNK_SIZE  
=> 10000);
END;
/

clip_image002[4]

 

위 결과에서 대략적으로 확인할 수 있듯이, Chunk 10,000개의 Row로 분할되었다. (예제 테이블은 1부터 1백만까지의 순번을 ID값으로 생성했음)

 

참고로, ROWID 분할(CREATE_CHUNKS_BY_ROWID procedure) 했을 때는 START_ROWID, END_ROWID에 값이 생성되고, NUMBER Column 분할(CREATE_CHUNKS_BY_NUMBER_COL)했을 때는 START_ID, END_ID에 값이 생성된다.

 

-- 작업 배분 균등 확인
-- Chunk START_ID, END_ID range 추출한 Row Count
SELECT  B.CHUNK_ID, COUNT(A.ID) ROW_COUNT
 
FROM  Z_DPE_TEST_TAB A,

       
(
       
SELECT  CHUNK_ID, START_ID, END_ID
         
FROM
  USER_PARALLEL_EXECUTE_CHUNKS
        
WHERE  TASK_NAME = 'DPE_TEST(BY NUMBER)'

       
) B
 
WHERE  A.ID BETWEEN B.START_ID AND B.
END_ID
 
GROUP  BY B.
CHUNK_ID
 
ORDER  BY B.CHUNK_ID;


clip_image004

 

-- Chunk START_ID, END_ID range 추출한 Row 전체 Count
SELECT  SUM(COUNT(A.ID)) ROW_COUNT
 
FROM  Z_DPE_TEST_TAB A,

       
(
       
SELECT  CHUNK_ID, START_ID, END_ID
         
FROM
  USER_PARALLEL_EXECUTE_CHUNKS
        
WHERE  TASK_NAME = 'DPE_TEST(BY NUMBER)'

       
) B
 
WHERE  A.ID BETWEEN B.START_ID AND B.
END_ID
 
GROUP  BY B.CHUNK_ID;


clip_image006

Row Count의 합계는 1,000,000 으로 전체 데이터 건수와 일치한다.

 

----------------------------------------------------------------------------------------------------
-- 3단계: 작업 실행
DECLARE
  L_SQL_STMT
VARCHAR2(32767);
BEGIN
  L_SQL_STMT
:= 'UPDATE  Z_DPE_TEST_TAB
                    SET  VAL = ROUND(DBMS_RANDOM.VALUE(1,10000))
                        ,AUDSID = SYS_CONTEXT(''USERENV'',''SESSIONID'')
                  WHERE  ID BETWEEN :START_ID AND :END_ID'
;


  DBMS_PARALLEL_EXECUTE.RUN_TASK
(TASK_NAME      => 'DPE_TEST(BY NUMBER)',
                                 SQL_STMT      
=> L_SQL_STMT,
                                 LANGUAGE_FLAG 
=> DBMS_SQL.NATIVE,
                                 PARALLEL_LEVEL
=> 10);
END;
/

-- Chunk 상태별 Count
SELECT STATUS, COUNT(*) FROM USER_PARALLEL_EXECUTE_CHUNKS
 
WHERE TASK_NAME = 'DPE_TEST(BY NUMBER)' GROUP BY STATUS;


■ 작업 진행중

clip_image008

 

■ 작업 완료.

clip_image010

 

■ 동시 실행현황 확인

clip_image012

 

  • 10개의 Job Session이 실행되었음
  • Job Session 1만건의 Chunk를 대부분 10개씩 할당 받아 실행하였음
  • AUDSID: 71767 Job SessionChunk 9(9만건)를 할당 받아 실행했고, AUDSID: 71773 Job Session Chunk 11(11만건)를 할당 받아 실행하였음
  • , 전체 Chunk 개수(여기서는 100)보다 RUN_TASK <PARALLEL_LEVEL>이 적을 때 한 Job이 여러 Chunk를 할당 받아서 실행하며, 그 실행횟수는 Chunk의 분할정도가 균일하더라도 차이가 있을 수 있음

 

----------------------------------------------------------------------------------------------------
-- 4단계: 작업 완료 확인 작업 삭제
-- 작업 완료 확인
SELECT * FROM USER_PARALLEL_EXECUTE_TASKS;
-- 작업 삭제
BEGIN
  DBMS_PARALLEL_EXECUTE.DROP_TASK
(TASK_NAME => 'DPE_TEST(BY NUMBER)');
END;
/

clip_image014

 

여기까지 NUMBER Column에 의한 배분방식의 사례를 살펴보았다. 다음은 사용자 정의 SQL 기반으로 배분하는 사례를 살펴볼 예정이다.

Leave Comments


profile기술 너머의 통찰 

Recent Trackback