2. ROWID 分割方式並列処理ケース(DBMS_PARALLEL_EXECUTE)
Oracle DBMS_PARALLEL_EXECUTEを活用して、ROWID分割方式の並列処理のケースを見てみましょう。
前の記事で続く内容だ。
1. DMLジョブの並列処理の概要(DBMS_PARALLEL_EXECUTE)
2. ROWID分割方式並列処理事例
2.1。 ROWID分割方式並列処理ジョブの生成
CREATE_TASK( )でジョブを作成します。
-- 1단계: 작업생성 BEGIN DBMS_PARALLEL_EXECUTE.CREATE_TASK(TASK_NAME => 'DPE_TEST(BY ROWID)'); END; /
ジョブが生成された結果は、次のように確認できます。
-- 작업 생성 확인 SELECT * FROM USER_PARALLEL_EXECUTE_TASKS;
上記の結果からタスクが生成され、STATUSはCREATEDであることを確認できます。
参考までに、タスクのSTATUSはCHUNKED、CHUNKING、CHUNKING_FAILED、CRASHED、CREATED、FINISHED、FINISHED_WITH_ERROR、PROCESSINGの値を持ち、それぞれの意味は次のとおりです。
- CHUNKED:チャンクが作成され、まだジョブに割り当てられていません
- CHUNKING:チャンク作成中
- CHUNKING_FAILED:チャンク作成中に失敗しました
- CRASHED:タスク実行中にデータベースクラッシュまたはジョブプロセスのクラッシュが発生し、エラーの記録に失敗しました。
- REATED: Task が作成されました (まだチャンクは生成されません)
- FINISHED:すべてのチャンクがエラーなしで完了しました
- FINISHED_WITH_ERROR:すべてのチャンクを完了しましたが、いくつかのエラーが発生しました
- PROCESSING:Toskが実行を開始し、チャンクの一部は進行中または完了状態です
*参照: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_parallel_ex.htm#ARPLS67333
2.2.作業単位の分割
CREATE_CHUNKS_BY_ROWID( 、
、はBOOLEANタイプでTRUEの場合がRow Countを意味し、FALSEの場合、Block Countを意味します。
Z_DPE_TEST_TABテーブルのRow countを10,000件ずつに分割するチャンクを作成するには、次のように実行します。
-- 2단계: 작업 단위 분할 BEGIN DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID(TASK_NAME => 'DPE_TEST(BY ROWID)', TABLE_OWNER => USER, TABLE_NAME => 'Z_DPE_TEST_TAB', BY_ROW => TRUE, CHUNK_SIZE => 10000); END; /
作業単位の分割状態を確認してみましょう。
-- 작업 분할 상태 확인 SELECT * FROM USER_PARALLEL_EXECUTE_CHUNKS WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
分割された時点の各チャンクのSTATUSがUNASSIGNEDになっていることが確認できる。ちなみに、チャンクのSTATUSはUNASSIGNED、ASSIGNED、PROCESSED、PROCESSED_WITH_ERRORの値を持ち、各意味は次のとおりです。
- UNASSIGNED:チャンクが作成され、まだジョブに割り当てられていません
- ASSIGNED: チャンクがジョブに割り当てられ、実行中
- PROCESSED:ジョブがエラーなしで完了しました
- PROCESSED_WITH_ERROR:ジョブは完了しましたが実行中にエラーが発生しました
*参照: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_parallel_ex.htm#ARPLS67333
2.3。ジョブの実行
RUN_TASK( 、 、 、 )でジョブを実行します。
ここで、LANGUAGE_FLAGはOracleがSQL_STMTを処理する基準バージョンの意味であり、defaultとしてDBMS_SQL.NATIVEを使用すればよい。
参考までに、Oracle Documentの内容は次のとおりです。
- V6(or 0) specifies version 6 behavior
- NATIVE (or 1) specifies normal behavior for the database to which the program is connected
- V7(or 2) specifies Oracle database version 7 behavior
PARALLEL_LEVELは、同時に実行するジョブ(job)の数、すなわち並列度(DOP、Degree Of Parallelism)を意味し、作業単位であるチャンクの数と同じでも少なくてもよい。同じ場合は1つのジョブが1つのチャンクを処理し、小さい場合は1つのジョブが複数のチャンクを処理します。
-- 동시 실행현황 확인: 작업 실행전 SELECT AUDSID, COUNT(*) FROM Z_DPE_TEST_TAB GROUP BY AUDSID ORDER BY AUDSID;
ジョブ実行前にAUDSID別にCOUNTを確認してみると、すべてのデータがnullに設定され、まだ実行されていないことを確認できる。
それでは、ジョブを実行してみましょう。
-- 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 ROWID BETWEEN :START_ID AND :END_ID'; DBMS_PARALLEL_EXECUTE.RUN_TASK(TASK_NAME => 'DPE_TEST(BY ROWID)', SQL_STMT => L_SQL_STMT, LANGUAGE_FLAG => DBMS_SQL.NATIVE, PARALLEL_LEVEL => 10); END; /
実行するSQLは、2つのbind変数:START_IDと:END_IDで実行範囲を指定します。この変数名は別の方法で使用するとエラーが発生するので、必ずこの名前を使用してください。
ここで実行するSQLは、テストのためにVAL列にランダム値を更新し、AUDSID列に現在のSESSIONID値を更新して、どのセッションで現在の行を更新したかを確認するように作成しました。
ちなみに、AUDSID列はV$SESSION.AUDSIDと同じ意味です。各チャンク単位の作業に時間がかかる場合は、V$SESSIONをAUDSIDで照会してSession monitoringを行うことができます。
実行中に次のSQLを実行してみると、いくつかのSessionでいくつの行を更新しているか確認できます。
-- 동시 실행현황 확인: 작업 실행중 SELECT AUDSID, COUNT(*) FROM Z_DPE_TEST_TAB GROUP BY AUDSID ORDER BY AUDSID;
Session単位ではなくタスクが分割されたchunk別の進行状況を確認してみよう。
-- 작업의 Chunk별 진행상황/완료 확인 SELECT * FROM USER_PARALLEL_EXECUTE_CHUNKS WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
上記の結果からSTATUSがPROCESSEDに変更され、START_TS(開始時刻)、END_TS(終了時刻)が管理されることを確認することができる。
Chunkの状態別に進行状況を確認するには、次のSQLを実行します。
-- Chunk의 상태별 진행상황 SELECT STATUS, COUNT(*) FROM USER_PARALLEL_EXECUTE_CHUNKS WHERE TASK_NAME = 'DPE_TEST(BY ROWID)' GROUP BY STATUS;
上記の結果から、172個のチャンクに対してPROCESSED状態で完了したことが確認できます。ジョブが完了した後にキャプチャした画像で、1つの状態のみが記録されました。作業に時間がかかる場合は、状態別にチャンク数を確認できます。
2.4。ジョブ完了の確認と削除
DROP_TASK( )でジョブを削除します。
参考までに、削除しなかった場合、後で同じTASK_NAMEでジョブを作成すると、ORA-29497:重複したジョブ名(DUPLICATE_TASK_NAME)エラーが発生します。
-- 작업 완료 확인 SELECT * FROM USER_PARALLEL_EXECUTE_TASKS;
上記の結果から、TaskのSTATUSがFINISHEDで完了したことを確認することができる。
-- 4단계: 작업 완료 확인 및 작업 삭제 BEGIN DBMS_PARALLEL_EXECUTE.DROP_TASK(TASK_NAME => 'DPE_TEST(BY ROWID)'); END; /
DROP_TASK実行後にUSER_PARALLEL_EXECUTE_TASKSビューを再確認してみると、ジョブが削除されたことを確認できます。
ここまで、ROWID分割方式並列処理作業について簡単な事例を見てみた。
次に、ROWIDで分割された作業単位がどれほど均一であるか、欠けていないか、チャンク数とジョブ数(並列度)との間の相関関係はどのようなものかを見ていきます。
2件のフィードバック
コメントを残す
メールアドレスが公開されることはありません。
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWIDを使用して実行しましたが、タスクのステータスを見るとNO_CHUNKS状態が表示されますが、もし理由がわかりますか?
私がテストした環境はOracle 11g R2(11.2)でしたが、当時はNO_CHUNKS状態はありませんでした。
Google検索をしてみると次の内容がありますね。
———————————–
NO_CHUNKS: Table associated with the task has no chunks created
———————————–
*ソース:Oracle 19cドキュメント
https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_PARALLEL_EXECUTE.html#GUID-5581516D-AB22-4748-8476-C5BB38BE7E2F
ROWIDでブロックを分割しましたが、そのチャンク内のすべてのブロックがデータがないときにNO_CHUNKS状態になるようです。
私は最近、Oracleを使用していないため、テストが難しいです。
注意してください。