クエリ最適化
遅い SQL を速くするための考え方を解説します。実行計画(EXPLAIN)の読み方、インデックスが効く・効かない条件、典型的な直し方を扱います。
- 1.まず EXPLAIN で実行計画を見て、全件走査(Seq Scan)になっている重い箇所を特定する。
- 2.インデックスは WHERE / JOIN / ORDER BY の列に効くが、列を加工したり先頭以外で検索すると効かない。
- 3.“SELECT * をやめる・適切な索引を貼る・関数で列を包まない”が遅いクエリ改善の定番。
クエリ最適化とは
同じ結果を返す SQL でも、DB の処理の仕方しだいで速度は何百倍も変わります。クエリ最適化 とは、正しい結果はそのままに、DB がより少ない仕事で答えを出せるようにする作業です。勘で書き換えるのではなく、まず 実行計画 を見て事実を確認するのが出発点です。
実行計画を読む(EXPLAIN)
DB は SQL をそのまま実行するのではなく、「どの順でどう処理すれば速いか」の計画(実行計画)を立てます。それを見せてくれるのが EXPLAIN です。
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;
ANALYZE を付けると実際に実行して所要時間も出ます。注目すべき代表的な語は次の通りです。
| 計画に出る語 | 意味 | 速度の目安 |
|---|---|---|
| Seq Scan(全件走査) | 先頭から全行を読む | 大きな表だと遅い |
| Index Scan | インデックスで該当行に直行 | 速い |
| Rows | その段で扱う見積もり行数 | 想定とズレたら要注意 |
| Cost / actual time | 見積もりコスト・実測時間 | 大きい段がボトルネック |
大きなテーブルなのに Seq Scan で多くの行を読んでいたら、インデックスで改善できる可能性が高いサインです。
インデックスが効く条件・効かない条件
インデックスは「索引」です。WHERE や JOIN、ORDER BY で指定した列に索引があれば、DB は全件を見ずに該当行へ直行できます。ただし書き方しだいで索引は無効化されます。
| 効く例 | 効かない例 | 理由 |
|---|---|---|
WHERE email = 'a@x.com' | WHERE LOWER(email) = 'a@x.com' | 列を関数で包むと素の索引が使えない |
WHERE name LIKE 'tan%' | WHERE name LIKE '%tan' | 前方一致は索引可、中間・後方一致は不可 |
(a, b) の索引で WHERE a = 1 | 同索引で WHERE b = 2 だけ | 複合索引は先頭列から使う |
WHERE DATE(created_at) = '2026-06-06' のように列を関数や計算で包むと、その列の通常のインデックスは使われず全件走査になりがちです。created_at >= '2026-06-06' AND created_at < '2026-06-07' のように 列はそのまま、右側で範囲を表す 書き方に直すと索引が効きます。
遅いクエリの直し方
典型的な改善パターンを挙げます。
SELECT *をやめる: 必要な列だけ取れば、転送量が減り、索引だけで完結できる場合(カバリングインデックス)も増える。- 適切なインデックスを貼る:
WHEREやJOINの条件列、ORDER BYの列が候補。実行計画でSeq Scanだった箇所を狙う。 - 条件列を関数で包まない: 上記のとおり、加工は右辺へ。
- 不要な行を早く絞る: 結合の前に
WHEREで件数を減らすと、後段の処理が軽くなる。
-- before:全列取得+関数で索引が効かない
SELECT * FROM users WHERE LOWER(email) = 'a@x.com';
-- after:必要列のみ+列はそのまま(email に索引がある前提)
SELECT id, name FROM users WHERE email = 'a@x.com';
インデックスは検索を速くする一方、行を挿入・更新・削除するたびに索引側も更新が必要で、書き込みは遅くなり容量も増えます。よく使う検索条件に絞って貼り、使われていない索引は実行計画で確認して整理するのが健全です。
進め方のまとめ
- 遅いクエリを特定する(スロークエリログなど)。
EXPLAIN ANALYZEでどこが重いかを事実で確認する。- 索引追加・書き換えを1つずつ試し、再度計画を見て効果を検証する。
推測で書き換えず「計画を見て、直して、また計る」を回すことが、クエリ最適化の王道です。
データベース Article
クエリ最適化を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
クエリ最適化
比較で見る軸
難易度: intermediate / カテゴリ: データベース / タグ数: 4
導入後に効く点
インデックスは WHERE / JOIN / ORDER BY の列に効くが、列を加工したり先頭以外で検索すると効かない。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- データベース
- タグ数
- 4
判断チェックリスト
- 自社の用途が「クエリ最適化 / EXPLAIN」に近いか確認する。
- 強みである「まず EXPLAIN で実行計画を見て、全件走査(Seq Scan)になっている重い箇所を特定する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。