2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実行計画を読み解いてSQLを速くしよう!

Posted at

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つ。

  1. アクセスパス
  2. 結合方式
  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チューニングの "地図" みたいなもの。

  1. 予定のプランを見る
  2. 実績のプランを見る
  3. 悪い原因を探す
  4. 改善して比較する

この流れさえ押さえれば、どんな SQL でも必ず速くできます。

チューニング沼に迷い込んだ時は、ぜひ実行計画を覗いてみてください!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?