章: 第2章: データベース応用
テーブルが10万件を超えたとき、検索は突然遅くなる
テスト環境では速かった検索クエリが、本番データが100万件になったときに突然遅くなる——。これはインデックスがないまま、DBが全レコードを先頭から順に読み込む「フルスキャン」をしているからです。
インデックスは「目次」のような機能を持ち、「どのページに見つかるか」を事前に記録することで検索を高速化します。
インデックスの実装
-- インデックスの追加
CREATE INDEX idx_users_email ON users (email);
-- EXPLAINで利用確認
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
-- 複合インデックス(検索条件の順序に注意)
CREATE INDEX idx_orders_user_date ON orders (user_id, created_at);
インデックスあり vs なし
| 観点 | インデックスなし | インデックスあり |
| 100万件の検索 | 全件を駆ける | インデックスの重複絞り所に走る |
WHERE email = ? |
O(N) | O(log N) |
| INSERT/UPDATE | 早い | インデックス更新分、少し遅い |
| ストレージ使用量 | 小 | 増加する |
チェックポイント:
EXPLAINのtypeカラムがALL(フルスキャン)の場合はインデックスの追加を検討してください。refやrangeになればインデックスが利いています。
複合インデックスの設計ポイント
-- 「user_idで絞り込み、created_atでソート」のクエリに対応
CREATE INDEX idx_orders_user_date ON orders (user_id, created_at);
-- このインデックスは以下のクエリで有効
SELECT * FROM orders WHERE user_id = 1 ORDER BY created_at DESC;
-- これは有効でない(左端のカラムから使われないとインデックスが利かない)
SELECT * FROM orders WHERE created_at > '2024-01-01';
チェックポイント: インデックスが多すぎるとINSERT/UPDATEが遅くなります。クエリパターンを分析して「実際に引かれるカラム」に絞って設計しましょう。
まとめ & 次のステップ
- インデックスは検索クエリの
WHEREが指定するカラムに設定する EXPLAINで現在のクエリがインデックスを使っているかを定期的に確認する- 複合インデックスは「左端のカラムからしか利かない」ルールを覚える
次回はマイグレーション管理を学びます。DBスキーマの変更履歴をバージョン管理し、チーム開発に安全な変更を展開する方法です。