3. NUMBER Column 분할 방식 병렬 처리 사례 (DBMS_PARALLEL_EXECUTE)

Oracle DBMS_PARALLEL_EXECUTE 를 활용하여 NUMBER Column 분할 방식 병렬 처리 사례에 대해 살펴본다. 작업 생성, 작업 단위 분할, 작업 실행, 작업 완료 확인 및 삭제에 대한 내용이다.

이전 글에서 이어지는 내용이다.

2.5. 작업 단위 분할 상세 확인 (DBMS_PARALLEL_EXECUTE)

3. NUMBER Column 분할 방식 병렬 처리 사례

NUMBER Column에 의한 분할방식의 사례를 살펴보자. ROWID 방식과 거의 유사한데, 다음 항목만 조금 다르다.

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

* 참조 Oracle 문서: DBMS_PARALLEL_EXECUTE – CREATE_CHUNKS_BY_NUMBER_COL Procedure

3.1. 작업 생성

작업을 생성하는 방법은 차이가 없다.

-- 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)';

3.2. 작업 단위 분할

CREATE_CHUNKS_BY_NUMBER_COL(<TASK_NAME>, <TABLE_OWNER>, <TABLE_NAME>, <TABLE_COLUMN>, <CHUNK_SIZE>)로 작업 단위를 분할한다.

Z_DPE_TEST_TAB 테이블의 “ID”컬럼을 기준으로 10,000 건씩 분할하는 chunk를 생성하려면 다음과 같이 실행한다.

-- 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;

작업 단위의 분할 상태를 확인해 보자.

-- 작업 분할 상태 확인
SELECT *
  FROM USER_PARALLEL_EXECUTE_CHUNKS
 WHERE TASK_NAME = 'DPE_TEST(BY NUMBER)'
 ORDER BY START_ID;
작업 분할 상태
작업 분할 상태

위 결과에서 대략적으로 확인할 수 있듯이, 각 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)가 균등하게 잘 배분되었는지 확인해 보자.

-- 작업 분할 균등 확인
-- 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;
작업 분할 균등 확인
작업 분할 균등 확인

각 chunk의 START_ID와 END_ID로 테이블의 건수를 확인해 보면 10,000 건으로 잘 분할되어 있다.

-- 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;
chunk row count 합계 확인
chunk row count 합계 확인

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

3.3. 작업 실행

RUN_TASK(<TASK_NAME>, <SQL_STMT>, <LANGUAGE_FLAG>, <PARALLEL_LEVEL>)로 작업을 실행한다. 작업 실행 방법은 ROWID 방식과 동일하다.

-- 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;
/

실행하는 SQL은 ROWID 분할 사례와 거의 동일하나 WHERE 절의 조건 컬럼이 “ROWID”가 아니라 지정한 NUMBER 컬럼인 “ID” 인 것이 다르다.

실행 중에 Chunk 상태변화를 살펴보자.

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

작업이 진행중일 때는 다음과 같이 chunk의 상태가 UNASSIGNED -> ASSIGNED -> PROCESSED 로 변경되면서 처리된다.

작업 실행중 chunk 상태 확인
작업 실행중 chunk 상태 확인

작업이 완료되면 모든 chunk의 상태가 PROCESSED로 나타난다.

작업 완료 chunk 상태 확인
작업 완료 chunk 상태 확인

작업 완료후에 다음 SQL을 실행해 보면 몇 개의 Session에서 몇 개의 행을 update했는지 확인할 수 있다.

-- 동시 실행현황 확인
SELECT AUDSID, COUNT(*)
  FROM Z_DPE_TEST_TAB
 GROUP BY AUDSID
 ORDER BY AUDSID;
세션별 처리한 데이터 건수 확인
세션별 처리한 데이터 건수 확인

위 내용에서 다음을 알 수 있다.

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

3.4. 작업 완료 확인 및 삭제

DROP_TASK(<TASK_NAME>)로 작업을 삭제한다.

-- 4단계: 작업 완료 확인 및 작업 삭제
-- 작업 완료 확인
SELECT * FROM USER_PARALLEL_EXECUTE_TASKS;

-- 작업 삭제
BEGIN
  DBMS_PARALLEL_EXECUTE.DROP_TASK(TASK_NAME => 'DPE_TEST(BY NUMBER)');
END;
/
작업 완료 확인
작업 완료 확인

여기까지 NUMBER Column 분할 방식 병렬 처리 사례를 살펴보았다. 다음은 사용자 정의 SQL 기반으로 분할하는 사례를 살펴본다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

ko_KR한국어