頻出中 ⏱ 7分★★★★☆

実行計画

EXPLAIN の読み方・コスト・チューニング手順を完全習得

オプティマイザが SQL を実行する際に選んだ具体的な手順のツリー。EXPLAIN コマンドで確認でき、性能チューニングの最初の一歩。

SQL は「何を取りたいか」を書くが、「どうやって取るか」はオプティマイザが決める。実行計画はその「どうやって」を可視化するもの。
EXPLAIN SELECT * FROM 受注 WHERE 顧客ID = 'C01';

-- PostgreSQL の例(概念的な出力)
-- Index Scan using idx_顧客ID on 受注
--   Index Cond: (顧客ID = 'C01')
--   cost=0.43..4.45 rows=1 width=80
主要な操作(オペレーター)一覧
操作名意味性能
Index Scan / Index Seekインデックスを使った検索✅ 速い
Seq Scan / Full Table Scanテーブル全行スキャン⚠ 大テーブルで遅い
Index Only Scanインデックスだけで完結(カバリング)✅✅ 最速
Nested Loopネストループ結合内側にインデックスで高速
Hash Joinハッシュ結合大テーブル同士に有効
Sortソート操作メモリ超過でディスク使用
Bitmap Heap Scanビットマップを作ってからヒープ読み込み中規模の IN 条件等
① SQL をパース(構文解析)して内部表現に変換
② 論理的に等価な実行プランの候補を列挙
③ 統計情報(テーブル行数・カーディナリティ・列のヒストグラム)を使ってコストを推定
④ コストが最小のプランを選択して実行
統計情報が古いと誤ったプランが選ばれる。定期的に ANALYZE(PostgreSQL)/ UPDATE STATISTICS(SQL Server)を実行する。
cost=0.43..8.45 rows=10 width=80 の意味
項目意味
cost=0.43最初の行を返すまでのコスト(スタートアップコスト)
cost=..8.45全行を返し終えるまでの総コスト
rows=10返される推定行数
width=801 行あたりの推定バイト数

コストは単位(ディスクページ読み込み)を基準とした相対値。絶対値より親ノードと子ノードの大小関係が重要。

実行計画を見て行うチューニング
実行計画の症状原因改善策
Full Table Scan / Seq Scanインデックスなし・統計情報古いインデックス追加・ANALYZE 実行
Sort(大量行)ORDER BY / GROUP BY 列にインデックスなしソート列にインデックス追加
Hash Batches > 1ハッシュ表がメモリに収まらないwork_mem 増加・結合順序変更
rows 推定値と実際値の乖離統計情報が古いANALYZE / UPDATE STATISTICS
-- Oracle のヒント句(最終手段)
SELECT /*+ INDEX(c idx_顧客名) */
  c.顧客ID, c.顧客名
FROM   顧客 c
WHERE  c.顧客名 = '山田';
ヒント句はオプティマイザを上書きするため、統計情報を更新したりインデックスを変更するほうが先。ヒント句への依存はメンテナンスコストを上げる。

📝 理解度チェック

コストベースオプティマイザが実行計画を選択する基準はどれか?
実行計画で Seq Scan(フルスキャン)が出た場合に最初に確認すべきことはどれか?
統計情報が古い場合に発生する問題はどれか?

読了ボタンを押すとトップページの進捗に反映されます