Plan TableとPredicate Informationを別々に読んでいて、フィルタ条件がどのステップに効いているのか見誤ったことがあります。実行計画出力全体の構造をマップにして、迷わず参照できるようにしました。
Oracle 実行計画の出力を構成する 6 つの大セクションについて、それぞれの「ボリューム」「主な観点」「推奨読解フェーズ(STEP)」を一覧化したマップです。計画を読み始める前に全体像を掴む際に活用してください。
1. Plan Header
図1: 実行計画の全体構造マップ
- ボリューム: 数行
- 主な観点: SQL_ID / Child Number / Hash Value / Plan 取得元(カーソルキャッシュ or AWR)/ 取得時刻
- 読解フェーズ: STEP 1(最初に確認)
- 備考: 複数の Child Number がある場合、それぞれ異なるバインド変数値・実行環境向けの計画が存在する
2. Plan Table(ツリー本体)
- ボリューム: SQL の複雑度に比例(数行〜数十行)
- 主な観点: Id / Operation / Object Name / Rows(推定行数)/ Bytes / Cost(%CPU)/ Time — 読み解きの中心
- 読解フェーズ: STEP 2(全体把握)→ STEP 3(実行順追跡)
- 備考: アスタリスク(*)が付いた Id は Predicate Information に対応する述語がある
3. Predicate Information
- ボリューム: Plan Table のアスタリスク付きステップ数に比例
- 主な観点: access(インデックス絞り込み条件)と filter(行レベルフィルタ条件)の分類
- 読解フェーズ: STEP 4
- 備考: filter が多く access が少ない場合は「インデックスをくぐり抜けた後に大量の行を捨てている」可能性が高い
4. Column Projection
- ボリューム: 全ステップ分(フォーマット指定時のみ出現)
- 主な観点: 各ステップが親へ渡す列名・データ型・長さ
- 読解フェーズ: STEP 4(補助)
- 備考: SELECT * の使用で不要列が大量に流れていないか確認。ROWID の受け渡しパターンでのデータ取得漏れも検出可能
5. Note
- ボリューム: 数行〜十数行(条件次第で出力なしもある)
- 主な観点: 動的サンプリング / Cardinality Feedback / SQL Plan Baseline 使用 / SQL Patch / パラレル実行ヒント / 統計情報関連の警告
- 読解フェーズ: STEP 5
- 備考: 「dynamic statistics used」が出ていたら統計情報未収集の可能性あり。計画が不安定な原因として最初にチェックすべき
6. Statistics(実績値)
- ボリューム: ALLSTATS フォーマット時のみ(各ステップに追記)
- 主な観点: Starts(ループ実行回数)/ E-Rows(推定行数)/ A-Rows(実際の行数)/ Buffers(論理読込)/ Reads(物理読込)
- 読解フェーズ: STEP 3〜4(E-Rows と A-Rows の乖離を追跡)
- 備考: E-Rows と A-Rows が 10 倍以上乖離するステップがあれば、そのアクセスパスや結合順序が統計情報の誤りで決まっている疑いあり
Plan Table の主要操作カテゴリ一覧
Plan Table に現れる Operation は大きく以下のカテゴリに分類されます。PART 03〜09 で各カテゴリを詳述します。
| カテゴリ | 代表的な Operation | 本シリーズでの扱い |
|---|---|---|
| プランヘッダ・基本列 | Plan Header 全体・Rows / Cost / Time 列 | PART 03 |
| アクセスパス | TABLE ACCESS FULL / INDEX RANGE SCAN / INDEX UNIQUE SCAN / INDEX SKIP SCAN / ROWID SCAN | PART 04 |
| 結合操作 | NESTED LOOPS / HASH JOIN / SORT MERGE JOIN / CARTESIAN | PART 05 |
| ソート・集計・集合演算 | SORT ORDER BY / SORT GROUP BY / HASH GROUP BY / UNION-ALL / MINUS / INTERSECT | PART 06 |
| サブクエリ・ビュー | FILTER / VIEW / MERGE JOIN CARTESIAN / CONNECT BY | PART 07 |
| 述語情報・列投影 | Predicate Information (access/filter) / Column Projection | PART 08 |
| Note・統計 | Note セクション全体 / Statistics 実績列 | PART 09 |
| 診断シナリオ | —(応用) | PART 10 |
実行計画を読む際によくある誤り
| 誤り | 何が起きるか | 正しい読み方 |
|---|---|---|
| Plan Table だけ見て判断する | Note セクションの「dynamic statistics used」や SQL Plan Baseline 適用を見落とし、計画が不安定な根本原因を誤診する | Note セクション(STEP 5)を必ず確認して計画生成の前提条件を把握する |
| Cost が小さいので最適な計画と判断する | Cost はOptimizerの内部見積もりであり実際の実行時間と直結しない。統計情報が古ければ Cost は小さくても実際には遅い | ALLSTATS で E-Rows と A-Rows の乖離を確認し、実績値ベースで評価する |
| Predicate Information を確認しない | access ではなく filter になっている条件を見逃し、不要な大量行フィルタリングが発生していると気づかない | アスタリスク(*)が付いた Id の access と filter を必ず確認する |
| 複数 Child Number の存在を見落とす | 本番で想定外の計画が使われているのに Plan Header の確認不足で気づかない | Plan Header の Child Number と取得元(カーソルキャッシュ or AWR)を最初に確認する |