第13回: インデックス設計の基本 — 「遅い検索」の9割はインデックスで解決できる

章: 第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 早い インデックス更新分、少し遅い
ストレージ使用量 増加する

チェックポイント: EXPLAINtype カラムが ALL(フルスキャン)の場合はインデックスの追加を検討してください。refrange になればインデックスが利いています。

複合インデックスの設計ポイント


-- 「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スキーマの変更履歴をバージョン管理し、チーム開発に安全な変更を展開する方法です。

Related Articles