インデックス いんでっくす
インデックス索引検索高速化B-treeクエリ最適化パフォーマンス
インデックスについて教えて
簡単に言うとこんな感じ!
インデックスは「本の巻末索引」そのものだよ!分厚い辞書で「機械学習」という言葉を探すとき、最初から全ページをめくる代わりに、巻末の索引で「き→〇〇ページ」とすぐ飛べるよね。DBのインデックスも同じで、膨大なデータから目当ての行を一瞬で見つけるための仕組みなんだ!
インデックスとは
インデックス(Index・索引) とは、データベースのテーブルに対して検索を高速化するために作成する補助的なデータ構造です。「全行を先頭から順番に調べる(フルテーブルスキャン)」という遅い処理の代わりに、インデックスを使うことで「目的のデータがどこにあるか」を素早く特定できます。
実務では、インデックスの有無が検索の速さに数百倍〜数万倍の差をもたらすことがあります。100万件のユーザーテーブルから「メールアドレスが一致するユーザー」を探す場合、インデックスなしでは100万行を全部調べますが、インデックスがあれば数ステップで到達できます。
ただし、インデックスはデータ更新(INSERT/UPDATE/DELETE)のたびに一緒に更新する必要があるため、書き込み処理のコストが増加します。また、インデックス自体がディスクスペースを消費します。「どのカラムにインデックスを貼るか」は、読み取りと書き込みのバランスを考えた設計判断が必要です。
インデックスの種類
| 種類 | 特徴 | 向いているケース |
|---|---|---|
| B-treeインデックス | 最も一般的。等値・範囲検索に強い | =・BETWEEN・>・ORDER BY |
| ハッシュインデックス | 等値検索に特化して高速 | = のみ(範囲検索は不可) |
| GINインデックス | 配列・JSONの中身・全文検索に対応 | 配列型・JSONBカラム・全文検索 |
| GiSTインデックス | 地理情報・幾何データに対応 | 位置情報・半径検索など |
| 複合インデックス | 複数カラムをまとめてインデックス | 複数条件での絞り込み |
| 部分インデックス | 特定の条件行だけにインデックス | WHERE is_active = TRUE の行だけなど |
| 唯一インデックス(UNIQUE) | 値の一意性を保証しつつ高速化 | メールアドレス・社員番号など |
歴史と背景
- 1970年代 — IBM の ISAM(Indexed Sequential Access Method)がインデックスの先駆け。磁気テープ・ディスクの逐次アクセスを改善する手法として登場
- 1972年 — B-tree(バランス木) のアルゴリズムが Bayer & McCreight により発表。現在も大多数のDBインデックスに使われる基本構造
- 1970〜80年代 — Oracle・DB2 など初期のRDBMSがB-treeインデックスを採用
- 1990年代 — ビットマップインデックス・ハッシュインデックスなど多様な種類が登場。DWH(データウェアハウス)向けの最適化が進む
- 2000年代以降 — クラウドDB・列指向ストレージの普及により、インデックスの設計戦略がより多様化。オプティマイザ(実行計画自動最適化)も高度化
B-treeインデックスの仕組み
-- インデックスの作成
CREATE INDEX idx_users_email ON users (email);
-- 複合インデックスの作成
CREATE INDEX idx_orders_user_date ON orders (user_id, created_at);
-- インデックスの確認(PostgreSQL)
SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'users';
-- インデックスが使われているか確認(実行計画)
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';
-- "Index Scan using idx_users_email" と表示されればOK
関連する規格・RFC
| 規格・RFC番号 | 内容 |
|---|---|
| ISO/IEC 9075 (SQL標準) | CREATE INDEX 文の基本仕様。ただし実装詳細は各DBMSに委ねられる |