はじめに
以下のクエリでテーブルスキャンの進捗を確認することができる。
内容
前提
実行環境は以下となる。
- OSバージョン
- Windows Server 2016 Standard
- Oracle Databaseバージョン
- Oracle Database 12C
利用場面
クエリを実行した時に、想定よりも実行が遅い時など、現在実行中のどのテーブルスキャンで時間がかかっているのか確認する際に使用する。
クエリ内のどのテーブルで、どれぐらいのテーブルスキャンなのかやフルスキャンなので、インデックススキャンなのかなどが分かるため、クエリ遅延の際の調査に利用できる。
確認方法
以下のクエリを実行する。
SELECT S.CLIENT_INFO,
SL.OPNAME,
SL.TARGET,
SL.MESSAGE,
SL.SID, SL.SERIAL#, P.SPID,
SL.SOFAR, SL.TOTALWORK,S.MACHINE,S.PROGRAM,GS.SQL_EXEC_START,
ROUND(SL.SOFAR/SL.TOTALWORK*100,2) "% COMPLETE"
FROM V$SESSION_LONGOPS SL, V$SESSION S, V$PROCESS P, GV$SESSION GS
WHERE P.ADDR = S.PADDR
AND SL.SID = S.SID
AND SL.SERIAL#=S.SERIAL#
AND TOTALWORK != 0
AND SOFAR <> TOTALWORK
AND S.SID = GS.SID(+)
確認内容
実行すると、現在、テーブルスキャンが実施されているクエリが一覧で出てくる。
% Completeで、現在のテーブルスキャンがどれだけ進んでいるか確認が可能。
もし、想定外のテーブルなどでフルスキャンが発生していたり、読み込みに時間がかかっている場合、チューニング対象として見ることもできる。
クエリの実行時間と、表示されているテーブルスキャンに時間がかかることは、許容できるものかの基準は必要となる。
そのため、日頃から実行されているクエリの実行時間や目安は基準として持っておくことをお勧めする。
注意点
Oracleの動的ビューのバグの関係で、アドレスが一致せずに出てこないこともある。
また、上記で出てくる進捗は、クエリ全体の進捗ではなく、あくまで読み込みが行われているテーブルスキャンまたはインデックススキャンの進捗のため、例えば、テーブルA、テーブルB、テーブルCを結合したSELECT文を実行した場合、テーブルAのテーブルスキャンの進捗が出て、100%で完了した後にテーブルBが再表示される。あくまでクエリ内で使っているテーブルの1つであることは認識しておく必要がある。
まとめ
この確認クエリ単体では、あまり役に立たないが、日頃の標準実行時間とテーブル読み込みの想定があることで、それが想定通りなのか、妥当な水準なのかを実行時に比較することができるため、便利なものになる。
コメント