はじめに
SQLを実務で扱っていると、「正しく書けているのに遅い」クエリに出会うことがあります。
とくに WHERE句の書き方がパフォーマンスに与える影響は大きく、たった一行の書き方で実行時間が数十倍変わることもあるんです。
本記事では、SQL Server・PostgreSQLなど主要RDBMSで共通して効果がある「WHERE句最適化テクニック」 を、実務ベースで解説していきます。
1. 関数を使うとインデックスが死ぬ
✖️悪い例
WHERE CONVERT(VARCHAR, date_column, 112) = '20250101'
✅良い例
WHERE date_column = '2025-01-01'
関数をWHERE句内で使うと、インデックスが効かなくなります(スキャンになる)。
日付や文字列の整形は事前に変換しておくか、列そのままで比較しましょう。
2. ORはCASE式 or UNIONで書き換える
✖️悪い例
WHERE type = 'A' OR status = 'active'
✅良い例(CASE式)
WHERE CASE
WHEN type = 'A' THEN 1
WHEN status = 'active' THEN 1
ELSE 0
END = 1
またはUNIONで分割して個別にインデックスを効かせることも可能です。
SELECT * FROM table WHERE type = 'A'
UNION
SELECT * FROM table WHERE status = 'active'
OR句はインデックスを無効化しやすく、フルスキャンを引き起こしがち。
状況に応じてリファクタリングしましょう。
3. NULLの扱いに気をつける(IS NULLは別物)
✖️うまくフィルタされない例
WHERE column = NULL
✅正しい書き方
WHERE column IS NULL
また、NOT IN と NULLの組み合わせにも注意です。
-- NGパターン(NULLが1つでも混じると全体が除外される)
WHERE id NOT IN (SELECT user_id FROM blacklist)
→ 代替:NOT EXISTSの使用を推奨
WHERE NOT EXISTS (
SELECT 1 FROM blacklist WHERE blacklist.user_id = main.user_id
)
4. LIKEの前方一致だけにする(%の位置が重要)
✖️悪い例(インデックス効かない)
WHERE name LIKE '%太郎'
✅良い例(インデックス有効)
WHERE name LIKE '太郎%'
先頭に%があるLIKEは全件スキャン確定。
全文検索が必要なときは、全文検索エンジン(pg_trgmやFREETEXTなど)に任せちゃいましょう。
5. 暗黙の型変換を回避する
✖️暗黙キャストが起きる例(index無効)
WHERE numeric_column = '123' -- 文字列リテラルとの比較
✅明示的に型を合わせる
WHERE numeric_column = 123
または、列側の型に合わせたリテラルにすること。
おまけ:WHERE句の評価順と条件の順番は関係ある?
結論から言うと、SQLエンジンは最適化処理を行うため、条件の順番は基本的に関係ないです。
ですが、人間の目で読んだときに重い条件は後ろに書いた方がバグ発見しやすいという利点があります。
自分とチームメンバーのためにも、わかりやすいクエリ文を書くことを意識しましょう。
まとめ
| 技 | 効果 |
|---|---|
| 関数を使わない | インデックスが効く |
| ORを分解する | 実行計画の分岐を回避 |
| NULLを正しく扱う | 意図しないフィルタミス防止 |
| LIKEは前方一致にする | インデックスの恩恵を受ける |
| 型変換を避ける | フルスキャン防止&速度向上 |
おわりに
WHERE句の書き方ひとつで、SQLのパフォーマンスは劇的に変わります。
特に大規模テーブルを扱う業務SQLでは、こうした小さな最適化が「爆速化のカギ」 になります。
この記事が「最近SQL遅いな…」と感じている方の一助になれば幸いです!
ストック・いいね・コメントでのフィードバック大歓迎!