長時間実行される処理の完了時間を予測する（Oracle Database 19c）

# 長時間実行される処理
Oracle Database 上で実行されるメンテナンス処理は長時間かかることがあります。６秒以上かかる操作について、Oracle Database では V$SESSION_LONGOPS ビューに情報が提供されます。このビューにはバックアップ、リカバリ、オプティマイザ統計の収集、検索処理などの処理で実行時間や予測時間の情報が格納されます。利用するには初期化パラメーター TIMED_STATISTICS または SQL_TRACE を TRUE に設定します。マニュアルは[こちら](https://docs.oracle.com/cd/F19136_01/refrn/V-SESSION_LONGOPS.html)です。

V$SESSION_LONGOPSビューの定義は以下の通りです。

|列名|データ型|説明|備考 |
|:---|:---|:---|:---|
|SID|NUMBER|セッション識別子||
|SERIAL#|NUMBER|セッション・シリアル番号||
|OPNAME|VARCHAR2(64)|操作説明||
|TARGET|VARCHAR2(64)|実行されたオブジェクト||
|TARGET_DESC|VARCHAR2(32)|ターゲットの説明||
|SOFAR|NUMBER|OPNAMEの作業量||
|TOTALWORK|NUMBER|OPNAMEで指定した合計作業量||
|UNITS|VARCHAR2(32)|測定単位||
|START_TIME|DATE|操作の開始時刻||
|LAST_UPDATE_TIME|DATE|前回更新時刻||
|TIMESTAMP|DATE|操作固有のタイムスタンプ||
|TIME_REMAINING|NUMBER|操作終了までの残り推定時間（秒）||
|ELAPSED_SECONDS|NUMBER|経過時間（秒）||
|CONTEXT|NUMBER|コンテキスト|詳細不明|
|MESSAGE|VARCHAR2(512)|統計サマリー・メッセージ||
|USERNAME|VARCHAR2(30))|ユーザーID||
|SQL_ADDRESS|RAW(4|8)|SQL文識別子||
|SQL_HASH_VALUE|NUMBER|実行計画識別子||
|SQL_ID|VARCHAR2(13)|SQL文識別子||
|SQL_PLAN_HASH_VALUE|NUMBER|実行計画ハッシュ値||
|SQL_EXEC_START|DATE|SQL文実行開始時刻||
|SQL_EXEC_ID|NUMBER|SQL実行識別子|V$SQL_MONITOR|
|SQL_PLAN_LINE_ID|NUMBER|実行計画のラインID||
|SQL_PLAN_OPERATION|VARCHAR2(30)|実行計画の操作名||
|SQL_PLAN_OPTIONS|VARCHAR2(30)|実行計画のオプション||
|QCSID|NUMBER|パラレル・コーディネータのセッション識別子||
|CON_ID|NUMBER|コンテナID||

# V$SESSION_LONGOPS ビューを検証
V$SESSION_LONGOPS ビューの定義はマニュアルに記載されていますが、列に出力される内容の多くはマニュアルには記載されていません。いくつかの操作を行い、各列に出力される内容を確認します。
TOTALWORK 列には全体の処理数が出力されます。ある時点まででに実際に完了している数値が SOFAR に示されます。これらの値の単位が UNITS 列です。UNITS列には以下ような値が出力されます。

|UNITS列の出力例|単位|
|:---|:---|
|Bytes|バイト|
|MB|メガバイト|
|KB/sec|キロバイト/秒|
|Objects|オブジェクト数|
|Sql Statements|SQL文|
|Partitions|パーティション数|
|Indexes|インデックス数|
|Blocks |ブロック数|
|Entries|エントリー数|
|Files|ファイル数|
|Vectors|ベクター数|
|PID|プロセスID|
|RCVID|受信ID|
|SCN+Time|SCNと時間|
|Seconds|秒|
|Times|回数|

OPNAME列には処理を行う操作が出力されます。

|OPNAME列の出力例|説明|
|:---|:---|
|Advisor|SQL Tuning Advisorの実行|
|RMAN: full datafile restore|RMAN によるリストア|
|RMAN: aggregate input|RMAN のデータ入力|
|RMAN: aggregate output|RMAN のデータ入力|
|RMAN: incremental datafile backup|RMAN の差分バックアップ|
|RMAN: full datafile backup|RMAN のフルバックアップ|
|SYS_EXPORT_SCHEMA_01|エクスポート処理（スキーマ単位）|
|Gather Table's Index Statistics|統計情報の取得|
|Gather Table Partition Statistics|パーティション・テーブルの統計情報収集|
|Gather Auto Statistics|自動統計情報の収集|

MESSAGE列には OPNAME 列で実行されている処理の詳細が出力されます。
|MESSAGE列の出力例|説明|
|:---|:---|
|SYS_EXPORT_SCHEMA_01: EXPORT : 1 out of 1 MB done|エクスポート処理|
|Gather Table's Index Statistics: Table SYS_EXPORT_SCHEMA_01 : 8 out of 8 Indexes done|エクスポート時の統計情報収集処理|
|RMAN: full datafile restore: Set Count 251: 142080 out of 142080 Blocks done|RMANによるリストア|
|RMAN: aggregate input: restore 489: 499 out of 765 780 Blocks done|RMAN DUPLICATEによるソースからの入力|
|RMAN: incremental datafile backup: Set Count 252: 215873 out of 215873 Blocks done |RMAN 増分バックアップ|
|Advisor:  : 4 out of 4 Sql Statements done| SQL Tuning Advisorの実行|

# アプリケーションから利用
V$SESSION_LONGOPS ビューはアプリケーション処理の中からも利用できます。
DBMS_APPLICATION_INFOパッケージを利用して長時間実行される処理の進行状況をビューに追加できます。下記は[マニュアル PL/SQLパッケージおよびタイプ・リファレンス](https://docs.oracle.com/cd/F19136_01/arpls/DBMS_APPLICATION_INFO.html#GUID-A5E0BCFA-229C-4EA7-BDE7-E926A4ED530C)に記載されたサンプルを一部修正して記載しています。

```SQL:
DECLARE
        rindex    BINARY_INTEGER;
        slno      BINARY_INTEGER;
        totalwork number;
        sofar     number;
        obj       BINARY_INTEGER;
 
BEGIN
        rindex := DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT;
        sofar := 0;
        totalwork := 10;
 
        WHILE sofar < 10 LOOP
          -- update obj based on sofar
          -- perform task on object target
 
          sofar := sofar + 1;
          DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS(rindex, slno,
            "Operation X", obj, 0, sofar, totalwork, "table", "tables");
        END LOOP;
END;

```

Author: Noriyoshi Shinoda / Date: Marchi 13, 2023