oracle

Oracle V$SQLに関する少しマニアックな情報

実行したSQLを分析する際に何かと確認するのがV$SQLですが、他では書かれていない少しマニアックな事を記載してみました。個人的にはパフォーマンスチューニングを行う際、意識している項目です。EXECUTIONS、CPU_TIME、ELAPSED_TIME等累積値で持つ項目がいくつかありますが、これらはLAST_LOAD_TIMEが更新されるタイミングでリセットされる点気を付けましょう。

項目名 解説
SQL_ID

SQLテキストのハッシュ値。「人の目で見て同じに見えるSQL」であっても、改行や空白が入ると異なるSQL_IDとなります。

EXACT_MATCHING_SIGNATURE

正規化されたSQLテキストに対して計算されたシグネチャ。正規化とは「空白の削除と非リテラル文字列の大文字化」との事です。SQLテキストとしては異なるけれど、SQLの意味的には同じSQLを見つけ出すには利用できそうですが、バインド変数を利用した際は注意が必要です。バインド変数名が異なれば他が同じでも異なる値になります。また、コメントが変更しても変わってきます。

PLAN_HASH_VALUE

実行プランを一意にあらわすコード値。実行プランの変更はこの値で判断できます。

IS_REOPTIMIZABLE

統計フィードバックという機能によりハードパースのタイミングで事前に見積もったカーディナリティが実際の値と大きく乖離している事がわかった場合「Y」となり、次回実行の際には「再度ハードパースと最適化」が予約された事になる。2回目実行にて再度ハードパースが行われ「N」となる。
この統計フィードバック機能は初期化パラメータ OPTIMIZER_ADAPTIVE_REPORTING_ONLY=TRUEとする事でレポートモードとなり機能が動作しない。この場合「R」となる。

SQL_TEXT

SQLテキストの最初の1000文字が見れます。但し改行が除去されています。

SQL_FULLTEXT

SQLテキストが全て入っていますが、CLOBなので4000バイトを超える場合、参照に少し手間がかかります。

LAST_LOAD_TIME

『問合せプラン』がライブラリ・キャッシュにロードされた時刻。ようはハードパース実施時刻です。

PARSE_CALLS

パース実行回数(ハード、ソフトパース合算)

EXECUTIONS

ライブラリキャッシュにロードされてからの実行回数累計。addBatchメソッドで実行した場合、executeBatchメソッドでの実行回数がカウントされる。正常に実行し終えたあとにカウントUPされる。(初回実行中は0)
また大量レコードのselectが行われた場合複数回にわたってfetchが行われるがその場合最初のfetchが完了した時点でカウント1となる。

CPU_TIME

解析、実行およびフェッチの時間累計(マイクロ秒)。

ELAPSED_TIME

ライブラリキャッシュにロードされてからの実行時間累計(マイクロ秒)。
実行中(V$SESSIONのSTATUSがACTIVEの状態)は参照の都度カウントアップされていく様子が確認できるが、V$ACTIVE_SESSION_HISTORYのSESSION_STATEが”ON CPU”のタイミングでは動作しているにもかかわらずカウントが止まって見える。ON CPUの状態を脱すると本来加算される値が反映される。

FETCHES

SELECTが実行完了した場合に更新される累積値。INSERT/UPDATE/DELETEでは更新されない。(副問い合わせでselectが使われても更新されない)。

ROWS_PROCESSED

実行し終えてから値は更新(加算)される。

SELECT fetche回数 × fetchesize (累積値)
UPDATE 更新対象レコード数(累積値)
DELETE 削除対象レコード数(累積値)
INSERT INSERT対象レコード数(累積値)
SORTS DML実行の過程で発生したソート回数。(副問い合わせ含む)
USERS_OPENING 子カーソルをOpenしている数。同一SQLテキストを同時に実行している間カウントUPされるが、停止とともに0になる。(EXECUTIONSや、ELAPSED_TIMEはライブラリキャッシュにロードされて(LAST_LOAD_TIMEの更新)からの累積値であるのに対し、当項目は「その瞬間」の値である)例として、5つのセッションから同時に同じSQLテキストを実行している場合、当項目は5になる。

USERS_EXECUTING

子カーソル(当SQL)を実行しているユーザ数。USER_OPENINGと同様で「その瞬間」の値で更新されていく。USER_OPENINGと同じ値になりそうですがそうはならないようです。観察しているとUSERS_OPENING≧USERS_EXECUTINGとこんな感じです。USER_OPENING=4なのにこちらは0なんて事もあります。

MODULE
ACTION

DBMS_APPLICATION_INFO.SET_MODULEをコールして設定する。SQL文の初回解析時に実行中であったモジュール名とアクション名。問い合わせプランが更新されて(LAST_LOAD_TIMEの更新)も初回解析時に設定されたモジュール名、アクション名は更新されない。正直ちょっと使い辛い、、
sys.dbms_shared_pool.purge()を使って共有プールからパージしたとしても初期解析時の値は固定されるようだ。ALTER SYSTEM FLUSH SHARED_POOLで共有プールをフラッシュした場合はこの値もクリアされる。V$SESSIONではMODULE/ACTION値共、常に最新の値が確認できる。
LAST_ACTIVE_TIME 当子カーソルが最後にアクティブになった時刻。ようは最後に動作した時刻。開始した時刻ではなく正常終了した時刻
APPLICATION_WAIT_TIME 行ロックや、テーブルロックによって待たされた時間(マイクロ秒)
CONCURRENCY_WAIT_TIME ラッチなどによって待たされた時間(マイクロ秒)
CLUSTER_WAIT_TIME キャッシュフィージョンによって発生した待ち時間?(マイクロ秒)
USER_IO_WAIT_TIME cell single block physical read、read by other session、db file sequential read、db file scattered read、などおなじみの待ち時間(マイクロ秒)
個人的によく参照する項目
select INST_ID,SQL_ID,CHILD_NUMBER
,PLAN_HASH_VALUE,LAST_LOAD_TIME,LAST_ACTIVE_TIME
,SQL_PLAN_BASELINE,SQL_PROFILE
,EXECUTIONS,ELAPSED_TIME,CPU_TIME,ROWS_PROCESSED,FETCHES,SORTS
,USERS_OPENING,USERS_EXECUTING
,APPLICATION_WAIT_TIME
,CONCURRENCY_WAIT_TIME
,CLUSTER_WAIT_TIME
,USER_IO_WAIT_TIME
,SHARABLE_MEM    -- この子カーソルが使用している共有メモリーのバイト数
,PERSISTENT_MEM  -- 子カーソルの存続期間に使用されるメモリーの固定バイト数
,SQL_TEXT
from GV$SQL
 where SQL_ID = 'gngtvs38t0060'
order by INST_ID,SQL_ID,CHILD_NUMBER
;
スポンサーリンク
コピペで使う