1. 実行計画とは?
SQL がデータを"どう取りに行くのか"まとめた 処理の道順(ナビ) です。
裏側でどんな風に動いているか、全部丸見えになります。
2. 実行計画が重要な理由
実行計画を見れば、SQL が遅い理由がだいたい分かります。
- 全表走査してない?
- 結合順がおかしくない?
- インデックス無視して暴走してない?
- 行数の見積りズレすぎてない?
とくに"遅い SQL の原因探し"では、まずここを見るのが鉄板です。
よく見る実行計画の項目まとめ
| 項目 | 説明 |
|---|---|
| Access Path | INDEX / FULL SCAN などのアクセス方法 |
| Join Method | NESTED LOOPS / HASH JOIN などの結合方式 |
| Cost | オプティマイザが計算した相対コスト |
| Cardinality | 見積り行数。ズレてたら赤信号 |
| Predicate | WHERE 条件の適用ポイント |
Oracle 実行計画の扱い方
3. ステップで理解する:作成 → 確認 → 比較 → 改善
● ステップ1:まずは"予定のプラン"を作る(EXPLAIN PLAN)
SQL を実行せずに、Oracle に「この SQL、どう動かすつもり?」と聞く。
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE employee_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
ここで見るポイント - FULL SCAN してない?
- インデックス使ってる?
- 変な結合順になってない?
"初見チェック"みたいな感じです。
● ステップ2:実際に SQL を動かして"本当のプラン"を見る
予定と実際は違うことが多いので、必ず実際の動きも確認します。
SELECT * FROM employees WHERE employee_id = 100;
SQL_ID を拾って...
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(
sql_id => '<実際のSQL_ID>',
cursor_child_no => NULL,
format => 'ALLSTATS LAST'
));
ここで見るポイント - 予定(EXPLAIN)と動き(実績)がズレてない?
- とくに Cardinality(行数見積り)が、実績と大違いじゃない?
- 物理読み込み・論理読み込みが、無駄に多くない?
● ステップ3:実行計画を見て"何が遅いのか"を探す
考える観点は、だいたい次の4つ。
- アクセスパス
- 結合方式
- 行数見積りのズレ
- 無駄なソート・I/O
例:
employee_id = 100 の1件だけ欲しいのに
TABLE ACCESS FULL employees
→ 100% おかしい。インデックス効いてない疑惑。
● ステップ4:改善・プラン比較そして仕上げる
改善案を試しつつ、効果を比較する段階。
SELECT /*+ INDEX(employees emp_idx1) */ *
FROM employees
WHERE employee_id = 100;
見るポイント - FULL SCAN → INDEX SCAN に変わった?
- 実行時間・読み込み量は減った?
改善前後の差分を見るのがいちばん効きます。
よくある"悪い例"と改善方法
例1:暗黙変換でインデックスがぶっ壊れる
WHERE employee_id = '100' -- NUMBER に文字列!
Oracle 内部で TO_NUMBER(employee_id) されるので
インデックスが完全に無効化 されます。
改善
WHERE employee_id = 100
例2:関数を使ったせいでインデックスが死ぬ
WHERE TO_CHAR(hire_date, 'YYYY') = '2020'
列に関数をかけると、基本インデックスは効きません。
改善
WHERE hire_date >= DATE '2020-01-01'
AND hire_date < DATE '2021-01-01'
例3:複合インデックスを"正しい順番"で使えていない
複合インデックス (col1, col2) があるのに...
WHERE col2 = 'X'
これは col1 をすっ飛ばすので効きません。
改善 - WHERE の条件順をインデックス順に寄せる\
- 必要なら新しいインデックス作成
まとめ
実行計画はSQLチューニングの "地図" みたいなもの。
- 予定のプランを見る
- 実績のプランを見る
- 悪い原因を探す
- 改善して比較する
この流れさえ押さえれば、どんな SQL でも必ず速くできます。
チューニング沼に迷い込んだ時は、ぜひ実行計画を覗いてみてください!