Wednesday, February 18, 2009

oracle sub cursor

サブカーソルというものもあるって、面白い

[Oracle] V$SQL と V$SQLAREA と子カーソル

テーマ:DB-設計・構築・管理
V$SQL と V$SQLAREA は、共に共有プールにキャッシュされているSQLの統計情報を参照する動的パフォーマンスビューです。

両者は構成列が非常に似ており一見どこが違うのかよくわかりませんが、V$SQLAREA は親カーソルつまり SQL 単位の統計情報、V$SQL は子カーソル単位の統計情報を示すという点が異なります。

V$SQLAREA には親カーソルの SQL識別子である SQL_ID ごとに1レコードが存在し、VERSION_COUNT という列に該当する親カーソルが持つ子カーソルの数を持ちます。

V$SQL には子カーソルの数に応じて SQL_ID ごとに複数のレコードが存在し、CHILD_NUMBER という列に子カーソルの番号を持ちます。

※SQL_ID は Oracle10g から追加された列です。

実際に両者を比較してみると、多くの場合、1つの親カーソルに対して1つの子カーソルとなっているようですが、1つの親カーソルに対して複数の子カーソルを持つものも少なからず存在するようです。

複数の子カーソルを持つ SQL とは、つまり何らかの理由によって既存の子カーソルが共有されなかったために新たな子カーソルが増えていったもので、それぞれの子カーソルは実行計画などが異なります。

既存の子カーソルが共有されなかった理由は V$SQL_SHARED_CURSOR を参照すればわかるようです。

V$SQL_SHARED_CURSOR には子カーソルが共有されなかった理由を示す以下のような列が定義されており、該当する理由の列に'Y'がセットされています。

説明
UNBOUND_CURSOR 既存の子カーソルが十分に構築されていない(最適化されていない)
SQL_TYPE_MISMATCH SQL の型が既存の子カーソルに一致しない
OPTIMIZER_MISMATCH オプティマイザの環境が既存の子カーソルに一致しない
OUTLINE_MISMATCH アウトラインが既存の子カーソルに一致しない
STATS_ROW_MISMATCH 既存の統計が既存の子カーソルに一致しない
LITERAL_MISMATCH 非データのリテラル値が既存の子カーソルに一致しない
SEC_DEPTH_MISMATCH セキュリティ・レベルが既存の子カーソルに一致しない
EXPLAIN_PLAN_CURSOR 子カーソルがEXPLAIN PLAN カーソルであり、共有する必要がない
BUFFERED_DML_MISMATCH バッファ付きDML が既存の子カーソルに一致しない
PDML_ENV_MISMATCH PDML 環境が既存の子カーソルに一致しない
INST_DRTLD_MISMATCH ダイレクト・ロード・インサートが既存の子カーソルに一致しない
SLAVE_QC_MISMATCH 既存の子カーソルはスレーブ・カーソルであり、新しい子カーソルがコーディネータによって発行された(または、既存の子カーソルがコーディネータによって発行されていて、新しい子カーソルがスレーブ・カーソルである)
TYPECHECK_MISMATCH 既存の子カーソルが十分に最適化されていない
AUTH_CHECK_MISMATCH 既存の子カーソルに対する認可/ 翻訳チェックに失敗した
BIND_MISMATCH バインド・メタデータが既存の子カーソルに一致しない
DESCRIBE_MISMATCH 子カーソルに対する記述中に、タイプ・チェック・ヒープが存在していない
LANGUAGE_MISMATCH 言語処理が既存の子カーソルに一致しない
TRANSLATION_MISMATCH 既存の子カーソルのベース・オブジェクトが一致しない
ROW_LEVEL_SEC_MISMATCH 行レベルのセキュリティ・ポリシーが一致しない
INSUFF_PRIVS 既存の子カーソルが参照するオブジェクトの権限が不十分である
INSUFF_PRIVS_REM 既存の子カーソルが参照するリモート・オブジェクトの権限が不十分である
REMOTE_TRANS_MISMATCH 既存の子カーソルのリモート・ベース・オブジェクトが一致しない
LOGMINER_SESSION_MISMATCH
INCOMP_LTRL_MISMATCH

No comments: