、 、 )で作業単位を分割します。
は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)';
ステップ2:ジョブ分割の状態を確認する
分割された時点の各チャンクの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;
ステップ3:同時実行状況確認(作業実行前)
ジョブ実行前に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;
ステップ3:同時実行状況の確認(作業実行中)
Session単位ではなくタスクが分割されたchunk別の進行状況を確認してみよう。
-- 작업의 Chunk별 진행상황/완료 확인
SELECT *
FROM USER_PARALLEL_EXECUTE_CHUNKS
WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
ステップ3:タスクのChunk別進行状況/完了確認
上記の結果から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;
ステップ3:Chunkの状態別進行状況を確認する
上記の結果から、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;
/
ステップ4:ジョブ完了の確認とジョブの削除
DROP_TASK実行後にUSER_PARALLEL_EXECUTE_TASKSビューを再確認してみると、ジョブが削除されたことを確認できます。
ここまで、ROWID分割方式並列処理作業について簡単な事例を見てみた。
次に、ROWIDで分割された作業単位がどれほど均一であるか、欠けていないか、チャンク数とジョブ数(並列度)との間の相関関係はどのようなものかを見ていきます。
タグ: ORACLE DBMS_PARALLEL_EXECUTE 並列処理 DML Parallel Processing DML並列処理
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を使用していないため、テストが難しいです。
注意してください。