📝 なぜこの記事を書いたのか
これまで自分は「インデックス=索引」「つけると速い」
くらいの なんとなくの理解 でデータベースを触ってきました。
しかし、実際に大規模データで処理が遅くなる場面に遭遇すると
- どこにインデックスを張るべきか判断できない
- 無駄なインデックスが逆に性能を落としてしまう
- クエリ改善の方向性が見えない
といった問題にぶつかります。
今回、インデックスの効果を実際に体験したのをきっかけに、
改めて理解し直すために作成しました。
🏷 目次
1. インデックスとは?
インデックスとは、データベースに付与する
「検索専用に最適化されたデータ構造」 のこと。
テーブル本体とは別に
- 検索しやすい
- ソート済みで
- 探索の手順が少ない
といった特徴を持つ B-Tree(または類似構造) を保持します。
👉 本体:ただのデータ並び
👉 インデックス:検索に特化した“索引”構造
2. インデックスの主な用途
① WHERE 句の高速検索
WHERE email = 'example@test.com'
② ORDER BY の高速化
ソート済みインデックスを利用。
③ JOIN の高速化
外部キー側にインデックスがあると結合が高速化。
④ UNIQUE 制約の実現
3. なぜ高速になるのか?(ロジカル・定量的説明)
■ インデックスなし:フルスキャン(O(N))
例えば100万件のテーブルなら
最大100万件すべて見る必要がある。
■ インデックスあり:木構造探索(O(log N))
B-Tree を使うと、
探索回数は 3〜4回程度 にまで減る。
■ 定量比較
| 行数 | フルスキャン | インデックス |
|---|---|---|
| 1,000 | 1,000回 | 3〜4回 |
| 100,000 | 100,000回 | 3〜4回 |
| 1,000,000 | 1,000,000回 | 3〜4回 |
| 10,000,000 | 10,000,000回 | 4〜5回 |
👉 桁違いの速さ
4. 日常例:あいうえお順の社員名簿で理解する
インデックスを直感的に理解するために 社員名簿の検索 を例に説明します。
■ インデックスなし(五十音順で並んでいない名簿)
「佐藤さんを探す」ときは、
- 頭から1人ずつチェック
- 田中
- 松本
- …
-(最悪)全員チェック
👉 これはまさに テーブルフルスキャン(O(N))。
■ インデックスあり(五十音順名簿)
同じ社員名簿でも、五十音順に整理されていると:
- 「あ行 → 違う、飛ばす」
- 「か行 → 違う、飛ばす」
- 「さ行 → 対象」
- さ/し/す…の範囲へ絞る
- 佐藤を発見
👉 人間の探索行動はまさに O(log N) の動きに近い。
■ 比較表
| 見方 | 方法 | コスト |
|---|---|---|
| インデックスなし | 全員順番にチェック | O(N) |
| インデックスあり | 行の塊を飛ばしつつ絞り込む | O(log N) |
5. インデックスを使うときの注意点
- INSERT / UPDATE が遅くなる
- 低選択性(true/false)は効果が薄い
- 複合インデックスは左側が重要
- 何でも張ると逆に遅くなる
6. まとめ
- インデックスは検索専用構造(索引)
- フルスキャン:O(N)
- インデックス:O(log N)
- 五十音順名簿の例が直感的で理解しやすい
- 適切な運用・設計が必要