Plan Header

Plan Header は DBMS_XPLAN.DISPLAY_CURSORDISPLAY_AWR が出力する最初の数行で、この計画が「どの SQL で」「いつ取得されたか」を識別するメタ情報です。

Plan Header の各項目と意味
項目意味影響箇所・着目点
SQL_IDSQL テキストを正規化した 13 桁の識別子AWR / V$SQL / V$SQL_PLAN を横断検索する際のキー。バインド変数値が違っても同じ SQL_ID
Child Number同一 SQL_ID に対して生成された計画バリアントの連番(0 から始まる)複数ある場合は異なる環境(NLS設定差・最適化ヒント差 等)で別計画が生成されている
Hash Value計画ツリー全体のハッシュ値計画が変化していないかを比較するときに使用。AWR では PLAN_HASH_VALUE として保存される
Plan取得元カーソルキャッシュ (DISPLAY_CURSOR) か AWR (DISPLAY_AWR) かを示す行キャッシュから取れない場合は「SQL_ID not found」エラーが出るため AWR を試す
Last Active Time / First Load Timeカーソルの最終アクティブ時刻・最初のロード時刻この計画がいつの性能問題に対応するかを時系列で確認

Child Number が複数ある場合の原因

  • NLS_DATE_FORMAT などのセッションレベルパラメータ差
  • Bind Peeking の結果として異なるバインド値で異なる計画が生成された
  • Adaptive Cursor Sharing(ACS)による再最適化
  • DDL 実行後の旧計画がフラッシュされず残存

Plan Table 基本列

Plan Table(ツリー本体)を構成するすべての列の意味を以下にまとめます。フォーマット文字列によって表示される列が異なります。

Plan Table の全列と意味・影響
列名意味影響箇所・着目点
Idステップ番号。アスタリスク(*)付きは Predicate Information に対応する述語ありPredicate Information との対応付けに使用
Operationこのステップで行われる処理の名称(TABLE ACCESS FULL、INDEX RANGE SCAN 等)アクセスパスと操作の中心的な情報
Name操作の対象オブジェクト名(表名・インデックス名・ビュー名等)インデックスが使われているかどうかの確認
Rowsオプティマイザが推定した出力行数(E-Rows)A-Rows との乖離で推定精度を確認
Bytes推定出力バイト数メモリ消費(PGA)の目安。HASH JOIN / SORT の規模感
Cost (%CPU)オプティマイザが計算したコスト(括弧内はCPUコスト比率)単体の絶対値より相対比較・計画変化の追跡に使う
Time推定実行時間(hh:mm:ss)あくまで推定値。実際の所要時間とは大きく乖離することが多い
TQ / IN-OUT / PQ Distribパラレル実行時のTable Queue番号・通信方向・分配方式パラレルの度合いとデータ分配のボトルネック確認
Pstart / Pstopパーティションプルーニング後の対象パーティション番号(開始/終了)KEY と表示される場合はパーティションが実行時まで確定しない動的プルーニング

Id 列 と Operation 列

Id 列 はツリーの各ノードに振られた連番です。Id 0 が最上位(SELECT STATEMENT 等)で、インデントが深いほど子ノード(先に実行される)です。

実行順の読み方

  • インデントが最も深いノードから実行される
  • 同一深さなら上から下へ
  • NESTED LOOPS では外側ループ(上)が駆動表、内側ループ(下)が被駆動表
  • HASH JOIN では Build 側(上)を先にハッシュテーブルに展開し、Probe 側(下)を流す
代表的な Operation 名の分類
Operation分類意味
SELECT STATEMENTルートノード実行計画ツリーの最上位。コスト欄に最終コストが表示される
TABLE ACCESS FULLアクセスパスフルテーブルスキャン(セグメント全体を読む)
TABLE ACCESS BY INDEX ROWIDアクセスパスROWID によるテーブルの行アクセス(インデックス経由)
INDEX RANGE SCANアクセスパスインデックスの範囲スキャン
NESTED LOOPS結合外側ループと内側ループを組み合わせた結合
HASH JOIN結合ハッシュテーブルを構築してプローブする結合
SORT ORDER BYソートORDER BY のソート処理
FILTERサブクエリ相関サブクエリの評価。ループ処理になりやすい

Rows 列 と Bytes 列

Rows はオプティマイザが算出した推定行数(Cardinality)です。これが実際の行数(A-Rows)と大きく乖離すると、選択されるアクセスパスや結合順序が最適でなくなります。

  • 読み方: ALLSTATS フォーマットでは E-Rows と A-Rows が並んで表示される。10倍以上乖離するステップが誤推定の根源
  • 閾値・注意点: 統計情報が古い・存在しない場合に乖離が大きくなる。動的サンプリングが有効なら Note セクションに記載される
  • 関連セクション: Note(dynamic statistics used の確認)/ 統計情報収集(DBMS_STATS)

Bytes はそのステップが出力すると推定されるデータ量です。HASH JOIN の Build 側や SORT 操作の Bytes が大きい場合、PGA が不足して一時領域(TEMP)へ SPILL が発生しやすくなります。

Cost 列 と Time 列

Cost はコストベースオプティマイザ(CBO)が内部で計算した相対的なコスト値です。

  • 読み方: 計画間の比較・計画変化前後の比較に使う。同じ SQL の計画が変わった後に Cost が跳ね上がっていれば劣化の可能性
  • 閾値・注意点: Cost の絶対値は環境依存のため「1000 が良い・悪い」という判断はできない。%CPU の括弧表記が低いと I/O 支配型の計画
  • 関連セクション: V$SQL の ELAPSED_TIME と組み合わせて評価

Time は推定実行時間(hh:mm:ss 形式)です。CBO の内部推定値であり、実際の実行時間とは無関係に近い精度であることが多いです。参考値として扱い、実際の性能は V$SQL の ELAPSED_TIME や AWR の SQL Statistics で確認します。

Pstart / Pstop 列(パーティション)

パーティション表に対するアクセスで出現します。オプティマイザがプルーニング後に読み込むパーティション範囲を示します。

Pstart / Pstop の代表的な値と意味
意味着目点
数値(例: 1, 3)静的プルーニング。コンパイル時にパーティション番号が確定している条件が定数リテラルの場合に発生。最も効率的
KEY動的プルーニング。バインド変数等で実行時にパーティション番号が決まるバインド変数プルーニング。実行時に絞り込まれるため計画上は全体に見えても実際は少数パーティション
KEY (SQ)サブクエリの結果でプルーニングサブクエリが返す値範囲によってパーティション数が変動
ROW REMOVE ITRIterator。ループ処理で各行のパーティションへアクセスNESTED LOOPS の内側でパーティションキーが駆動表の列の場合に出現。効率良し
1 〜 最大パーティション数全パーティションスキャン(プルーニングなし)WHERE 句にパーティションキーが含まれていないと発生。大量データ処理の兆候