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ステートメントのWHERE句にNUMBER列を使用する
*リファレンス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( 、
、Z_DPE_TEST_TABテーブルの「ID」列に基づいて10,000個ずつ分割するチャンクを作成するには、次のように実行します。
-- 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から100万までの順番を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;
各チャンクの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の合計は1,000,000で、総データ件数と一致します。
3.3。ジョブの実行
RUN_TASK( 、 、 、 )でジョブを実行します。ジョブの実行方法は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;
ジョブが進行中のときは、次のようにチャンクの状態がUNASSIGNED -> ASSIGNED -> PROCESSEDに変更されて処理されます。
ジョブが完了すると、すべてのチャンクの状態がPROCESSEDとして表示されます。
作業が完了したら、次のSQLを実行して、いくつかのSessionでいくつかの行を更新したことを確認できます。
-- 동시 실행현황 확인 SELECT AUDSID, COUNT(*) FROM Z_DPE_TEST_TAB GROUP BY AUDSID ORDER BY AUDSID;
上記の内容から次のことがわかる。
- 合計10個のジョブセッションが実行されました
- 各Job Sessionは、1万件のChunkをほとんど10個ずつ割り当てて実行した。
- AUDSID:71767 Job SessionはChunk 9個(9万件)を割り当てて実行し、AUDSID:71773 Job SessionはChunk 11個(11万件)を割り当てて実行した
- つまり、Chunkの総数(ここでは100個)よりRUN_TASKのこれが少ないと、1つのJobが複数のChunkを割り当てて実行します。
3.4。ジョブ完了の確認と削除
DROP_TASK( )でジョブを削除します。
-- 4단계: 작업 완료 확인 및 작업 삭제 -- 작업 완료 확인 SELECT * FROM USER_PARALLEL_EXECUTE_TASKS; -- 작업 삭제 BEGIN DBMS_PARALLEL_EXECUTE.DROP_TASK(TASK_NAME => 'DPE_TEST(BY NUMBER)'); END; /
ここまで NUMBER Column 分割方式並列処理の例を見てみた。以下は、カスタムSQLベースに分割するケースを見ていきます。