Note セクションとは
Note セクションは、オプティマイザや実行エンジンが計画に関する補足情報をテキストで通知する領域です。Plan Table からは読み取れない「なぜこの計画になったか」「どんな機能が関与しているか」を把握するために毎回確認するべきセクションです。
Note が空の場合は特記事項なし(標準的な計画)です。1 行でも出ている場合は必ず内容を確認してください。
Note 項目一覧
| Note の内容 | 意味 | 次のアクション |
|---|---|---|
| dynamic statistics used: dynamic sampling (level=N) | 統計情報が不足しているため動的サンプリングで補完した | DBMS_STATS で統計情報を収集する。N が高いほど精度は上がるが実行前サンプリングコストも高い |
| SQL Plan Baseline "SYS_SQL_PLAN_XXXXXXXX" used for this statement | SQL Plan Management (SPM) のベースラインが適用された | ベースラインが現状の最適計画かを確認。劣化した計画がベースラインで固定されている可能性 |
| SQL patch "XXXXXXXX" used for this statement | SQL Patch(ヒント相当の外部適用)が使われた | どのヒントが適用されているかを DBA_SQL_PATCHES で確認 |
| SQL Profile "XXXXXXXX" used for this statement | SQL Tuning Advisor が生成した SQL Profile が適用された | Profile の有効期限と内容を確認 |
| outline data is from a stored outline | 固定実行計画(Stored Outline)が使われている | Outline が最新の統計情報を反映しているか確認 |
| cardinality feedback used for this statement | Cardinality Feedback(12c 以前の機能)で再最適化が行われた | 最初の実行と 2 回目以降で計画が変わっている可能性。ALLSTATS で確認 |
| this is an adaptive plan | Adaptive Plans(12c 以降)が使われた。実行中に結合方式を切り替える可能性がある | 「- is the current option」と「+ is the chosen option」の表示で最終的な選択肢を確認 |
| Parallel query server usage: N DOP / actual DOP: N | パラレル実行が有効でDOP(Degree of Parallelism)が記載される | 計画上の DOP と実際の DOP のズレを確認。ダウングレードが発生しているか判断 |
| statistics are missing for table XXX | 表の統計情報がまったく存在しない | DBMS_STATS.GATHER_TABLE_STATS で収集。新規作成表や TRUNCATE 後に発生しやすい |
| automatic DOP: Computed Degree of Parallelism is N | AUTO DEGREE 設定でオプティマイザが自動的に DOP を決定した | 意図せずパラレル化されていないか確認 |
dynamic statistics used(動的サンプリング)
統計情報が存在しないか古い場合、オプティマイザは SQL 実行前に表の一部をサンプリングして仮の統計情報を生成します。これが「動的サンプリング」です。
- Level 1〜10: 数値が高いほど多くのブロックをサンプリング。精度は上がるがサンプリング自体にコストがかかる
- Level 11: 12c 以降の Adaptive Dynamic Sampling。オプティマイザが実行中に追加サンプリングを行う
- 影響: 動的サンプリングに頼っている場合、バッチ実行直後の最初の SQL が遅い(サンプリングコスト)ことがある
- 対処:
DBMS_STATS.GATHER_TABLE_STATSで正式な統計情報を収集することが根本対処
SQL Plan Baseline 使用の通知
SQL Plan Management (SPM) が有効な環境では、承認済みのベースラインプランが自動的に使われます。Note に SQL Plan Baseline "SYS_SQL_PLAN_XXXXXX" used と表示されます。
- 正常パターン: 計画の安定化が目的で意図的に SPM を使っている場合
- 問題パターン: テーブルが大幅に変化(大量データ追加・削除・再編成)したのにベースラインが古い計画を固定し続けている場合。現在の最適計画よりコストが高い計画で実行されている可能性がある
- 確認:
DBA_SQL_PLAN_BASELINESでベースラインの ACCEPTED / ENABLED / FIXED 状態を確認
Adaptive Plans(12c 以降)
12c 以降では Adaptive Plans 機能により、実行中にオプティマイザが統計情報の誤りを検知すると NESTED LOOPS と HASH JOIN を動的に切り替えることができます。
- Note の表示:
- is the current option(サブプラン)と+ is the chosen option(最終選択)がプランに出現 - 正常パターン: 統計情報の不確実性をランタイムで吸収できる強力な機能
- 問題パターン: Adaptive Plan が毎回切り替わっている場合は統計情報自体の品質改善が先決
- 無効化:
OPTIMIZER_ADAPTIVE_PLANS = FALSEで無効化可能(通常は推奨しない)
Statistics 実績値(ALLSTATS)
DBMS_XPLAN.DISPLAY_CURSOR(sql_id, child_number, 'ALLSTATS LAST') を使うと、Plan Table の各ステップに実績値の列が追加されます。
| 列名 | 意味 | 影響箇所・着目点 |
|---|---|---|
| Starts | そのステップが実行された回数(ループ回数) | NESTED LOOPS の内側ループの Starts = 外側ループの実行行数。多いと N 回 × アクセスコストが積み重なる |
| E-Rows | オプティマイザの推定行数(Estimated Rows) | A-Rows との比較基準 |
| A-Rows | 実際に出力された行数(Actual Rows) | E-Rows との乖離が大きいステップが誤推定の根源 |
| Buffers | 論理読込(バッファキャッシュアクセス)回数 | 多いほど CPU 消費・キャッシュ圧迫。ステップごとに見てホットなアクセスを特定 |
| Reads | 物理読込(ディスクまたはOSキャッシュ)回数 | 多いとI/O依存。Buffers との差が小さければキャッシュヒット率良好 |
| Writes | 物理書込(TEMP SPILL 等)回数 | ソート・ハッシュ結合が TEMP にスピルしているか確認 |
| OMem | Work Area の最適(1-pass)に必要なメモリ推定量 | 実際の PGA 割当と比較してサイジングを判断 |
| 1Mem | 1-pass モード(TEMP 1 回書き込み)で動作するのに必要なメモリ量 | OMem より小さく割り当てると 1-pass SPILL が発生 |
| Used-Mem | 実際に使用されたWork Areaメモリ量 | OMem と Used-Mem が一致していれば Optimal モード(SPILL なし) |
E-Rows vs A-Rows の乖離チェック
E-Rows と A-Rows の乖離は、「なぜこの計画が選ばれたか」を理解する最重要手がかりです。
乖離の判断基準
- 10 倍未満: 許容範囲。計画への影響は軽微
- 10〜100 倍: 要注意。このステップを起点に誤ったアクセスパス・結合順序が選ばれている可能性
- 100 倍以上: 問題あり。統計情報の収集・ヒストグラムの見直しが必要
乖離の主な原因と対処
| 原因 | 確認方法 | 対処 |
|---|---|---|
| 統計情報が古い | DBA_TAB_STATISTICS.LAST_ANALYZED が古い | DBMS_STATS.GATHER_TABLE_STATS |
| ヒストグラムが存在しない | DBA_TAB_COL_STATISTICS.HISTOGRAM = 'NONE' | METHOD_OPT => 'FOR COLUMNS SIZE AUTO' で収集 |
| 相関する列の組み合わせ(AND 条件) | E-Rows が AND 条件で過剰に小さく見積もられている | Extended Statistics(列グループ統計)を作成 |
| バインド変数ピークの誤り | 実行時のバインド値と計画生成時のバインド値が大きく異なる | Adaptive Cursor Sharing(ACS)の有効化・BIND_SENSITIVE ヒントの確認 |