本書の位置づけ
本書は、Oracle Database が出力する実行計画(Execution Plan)の各セクションについて、中級者を対象に「何を表すか」「どこを見るか」「悪い計画の判断基準」を体系化した定義書です。
対象バージョンは Oracle Database 12c 以降ですが、11g の実行計画とも構造はほぼ共通です。取得方法は DBMS_XPLAN.DISPLAY / DISPLAY_CURSOR / DISPLAY_AWR を想定しています。
想定読者
- EXPLAIN PLAN を2〜3回見たことがあり、Operation 列の意味は大体わかる方
- 「なぜこのアクセスパスが選ばれたのか」を自分で判断したい開発者/DBA
- 「Predicate Information や Note セクションが何のためにあるのか」を体系的に把握したい方
実行計画の取得方法
Oracle で実行計画を取得する主な方法は以下の 4 種類です。用途に応じて使い分けてください。
| 方法 | コマンド例 | 特徴・注意点 |
|---|---|---|
| EXPLAIN PLAN | EXPLAIN PLAN FOR <SQL>; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); | 実行前に推定計画を取得。バインド変数のペーク(覗き見)が行われないため実際と異なる場合あり |
| DISPLAY_CURSOR | SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id, child_number, 'ALLSTATS LAST')); | カーソルキャッシュから実際の実行計画を取得。実績行数(A-Rows)も確認可能 |
| DISPLAY_AWR | SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR(sql_id)); | AWR に保存された過去の実行計画を取得。DIAGNOSTICS PACK ライセンス必要 |
| V$SQL_PLAN | SELECT * FROM V$SQL_PLAN WHERE sql_id = '...'; | 個別列で詳細分析したい場合。DISPLAY_CURSOR の内部ソース |
実行計画出力の大構造(6セクション)
DBMS_XPLAN.DISPLAY_CURSOR のフォーマット 'ALLSTATS LAST' や 'ALL' で出力される実行計画は、大きく 6 つのセクションで構成されています。
- Plan Header — SQL_ID / Child Number / Hash Value / 取得時刻などのメタ情報
- Plan Table(ツリー本体) — Id / Operation / Object / 推定 Rows・Bytes・Cost・Time の主表。読み解きの中心
- Predicate Information — 各ステップで適用される Access Predicate(インデックス範囲絞り込み)と Filter Predicate(行レベルフィルタ)
- Column Projection — 各ステップが次の親ステップに渡す列リスト。不要列の混入を確認できる
- Note — オプティマイザが付けるメモ。動的サンプリング・Plan Baseline 使用・パラレル実行・SQL Patch 適用などを通知
- Statistics(実績値) —
ALLSTATS形式時のみ出現。A-Rows(実際の行数)/ Buffers / Reads などの実績カウンタ
推奨読解順 — チューニング起点を探す流れ
闇雲に全行を読むのではなく、まず大局(Plan Header)を確認してから、ツリーを「実行順(子から親へ)」に追い、Predicate・Note で原因を絞り込むのがセオリーです。
STEP 1: Plan Header の確認
SQL_ID・Child Number・取得時刻を確認。複数の子カーソルが存在する場合は各々の計画が異なる可能性あり。Hash Value で計画の同一性を識別。
STEP 2: Plan Table の全体像把握
ツリーの最大インデント(深さ)とステップ数で計画の複雑度を把握。Cost の高いノードに着目し、Full Table Scan が意図せず選ばれていないか確認。
STEP 3: 実行順の追跡(子→親)
インデントが最も深いノードから順に親を辿る。NESTED LOOPS の外側ループ・内側ループの区別、HASH JOIN のBuild側・Probe側を識別する。
STEP 4: Predicate Information の確認
Access Predicate でインデックスがどの列・どの範囲で絞り込まれているかを確認。Filter Predicate が多すぎると行レベル削除が遅延しているサイン。
STEP 5: Note・Statistics で原因特定
Note の警告(動的サンプリング・古い統計情報)を確認。ALLSTATS が取れる場合は E-Rows(推定)と A-Rows(実際)の乖離が大きいステップが誤推定の起点。
各定義シートの列構成
本シリーズの後続記事では、各セクションを以下の列構成でまとめています。
- No: 連番
- セクション/操作名: 実行計画上の英語表記
- 日本語訳: 通称・日本語訳
- 何を表すか: そのセクション/操作の意味と主目的
- 主要な列・項目: 着目すべきカラム名
- 読み方: 「ここをまず見る」「正常パターン」「問題パターン」の指針
- 閾値・注意点: 数値的な目安、罠、誤読されやすい箇所
- 関連セクション: 一緒に確認すべき他セクション・ビュー
- 使うシーン: そのセクションが特に有用な場面