章: 第3章: パフォーマンス最適化
「なんとなく遅い気がする」で最適化していませんか?
体感でクエリを最適化しようとすると、改善なのか改悪なのか判断できません。EXPLAINを使えば、MySQLがどのようにクエリを実行しているかを数値で把握できます。この回ではEXPLAINの読み方を整理し、根拠ある改善ができるようになりましょう。
EXPLAINが必要な理由
インデックスを追加しても、実際にMySQLがそのインデックスを使っているとは限りません。EXPLAINを使わずに「インデックスがあるから大丈夫」と判断するのは危険です。特に以下の場面でEXPLAINは必須です。
- クエリのレスポンスタイムが突然悪化したとき
- インデックスを追加・変更したとき
- JOINが多いクエリを書いたとき
EXPLAINの主要列:良い状態・悪い状態の比較
| 列名 | 良い状態 | 悪い状態 | 意味 |
type |
const, ref, range |
ALL, index |
テーブルスキャンの種類 |
key |
インデックス名が表示される | NULL |
使用されたインデックス |
rows |
少ない(数十〜数百) | 大きい(万単位) | スキャン行数の推定値 |
Extra |
Using index |
Using filesort, Using temporary |
追加処理の有無 |
チェックポイント: まず
typeがALL(フルスキャン)になっていないか確認しましょう。ALLが出ているならインデックス追加や条件の見直しが必要です。次にrowsが大きすぎないか、Extraにfilesortが出ていないかを確認します。
コードサンプル
EXPLAIN SELECT p.*
FROM posts p
WHERE p.user_id = 3
AND p.created_at >= '2026-01-01'
ORDER BY p.created_at DESC
LIMIT 50;
まとめ & 次のステップ
- EXPLAINを使うと、インデックスが実際に使われているかを数値で確認できます
- まず
type,key,rowsの3列を優先して見ましょう type: ALLはフルスキャンのサインで、インデックス追加の検討が必要ですExtra: Using filesortはソート処理が発生しており、ORDER BY列のインデックス見直しが有効です- 改善前後でEXPLAINの結果を並べて記録すると、チームへの説明材料になります
次回は N+1をSQL側で防ぐ を学びます。ループで個別取得する問題をSQL設計で根本から解消する方法を見ていきましょう。