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;
1단계: 작업 생성 확인
ステップ1:ジョブ作成を確認する

上記の結果からタスクが生成され、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)';
2단계: 작업 분할 상태 확인
ステップ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단계: 동시 실행현황 확인(작업 실행전)
ステップ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단계: 동시 실행현황 확인(작업 실행중)
ステップ3:同時実行状況の確認(作業実行中)

Session単位ではなくタスクが分割されたchunk別の進行状況を確認してみよう。

-- 작업의 Chunk별 진행상황/완료 확인
SELECT *
  FROM USER_PARALLEL_EXECUTE_CHUNKS
WHERE TASK_NAME = 'DPE_TEST(BY ROWID)';
3단계: 작업의 Chunk별 진행상황/완료 확인
ステップ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의 상태별 진행상황 확인
ステップ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 단계: 작업 완료 확인 및 작업 삭제
ステップ4:ジョブ完了の確認とジョブの削除

DROP_TASK実行後にUSER_PARALLEL_EXECUTE_TASKSビューを再確認してみると、ジョブが削除されたことを確認できます。


ここまで、ROWID分割方式並列処理作業について簡単な事例を見てみた。

次に、ROWIDで分割された作業単位がどれほど均一であるか、欠けていないか、チャンク数とジョブ数(並列度)との間の相関関係はどのようなものかを見ていきます。

2件のフィードバック

  1. アバター写真 newyemac より:

    DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWIDを使用して実行しましたが、タスクのステータスを見るとNO_CHUNKS状態が表示されますが、もし理由がわかりますか?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です