データベースインデックスとは?
データベースインデックス(索引)は、本の巻末索引と同じ仕組みです。ページを最初から全部めくらずに索引で目的の単語を探すように、インデックスはテーブルの全行をスキャンせずに目的の行を素早く見つけるためのデータ構造です。
インデックスがなければ、データベースはフィルター条件に合うデータを探すために**フルテーブルスキャン(Full Table Scan)**を実行します。100万件のデータがあれば最悪100万回の比較が必要です。適切なインデックスを作成すれば、これを数十〜数百回に抑えられます。
B-Treeインデックスの仕組み
ほとんどのRDBMS(PostgreSQL、MySQL、Oracle)は**B-Tree(バランスツリー)**を標準インデックス構造として使用します。
B-Treeの特性:
- 全リーフノードが同じ深さに位置(バランス維持)
- 各ノードはソートされたキーを保持
- キーを基準に左右の部分木を二分探索
- O(log n) の検索時間計算量
1,000万件のデータがあってもB-Treeの深さは約24段階に過ぎません。最大24回の比較で目的のデータを見つけられます。
インデックス作成の基本構文
-- 単一カラムインデックス
CREATE INDEX idx_users_email ON users(email);
-- ユニークインデックス
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);
-- 複合インデックス
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
-- インデックス削除
DROP INDEX idx_users_email;
-- インデックス一覧(PostgreSQL)
SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'users';
複合インデックスとカラム順序
複合インデックスは複数カラムをまとめた一つのインデックスです。カラム順序がパフォーマンスに決定的な影響を与えます。これを左端プレフィックスルールと呼びます。
CREATE INDEX idx_orders_composite ON orders(user_id, created_at, status);
-- インデックス使用可能(左から順に条件指定)
SELECT * FROM orders WHERE user_id = 1;
SELECT * FROM orders WHERE user_id = 1 AND created_at > '2026-01-01';
-- インデックス使用不可(先頭カラム条件なし)
SELECT * FROM orders WHERE created_at > '2026-01-01';
カーディナリティと選択性
カーディナリティはカラムのユニーク値の数を指し、インデックス効果を決定する重要な要素です。
| カラム | 値の例 | カーディナリティ | インデックス効果 |
|---|---|---|---|
| user_id | UUID | 非常に高い | 優れている |
| メールアドレス | 高い | 良好 | |
| status | paid/pending/failed | 低い(3種類) | 限定的 |
| gender | M/F | 非常に低い | ほぼなし |
カバリングインデックス
クエリに必要な全カラムがインデックスに含まれている場合、テーブル本体へのアクセスなしにインデックスだけで結果を返せます。
CREATE INDEX idx_users_covering ON users(id, name, email);
-- このクエリはインデックスだけで処理可能
SELECT id, name, email FROM users WHERE id = 123;
-- PostgreSQLのINCLUDEでカバリングインデックスを明示的に作成
CREATE INDEX idx_orders_user ON orders(user_id) INCLUDE (total_amount, status);
実行計画でインデックス効果を確認
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 1;
-- Index Scan → インデックス使用
-- Seq Scan → フルテーブルスキャン
インデックス設計の原則
- WHERE句のカラムを優先してインデックス作成
- JOIN条件(外部キー)には必ずインデックス
- ORDER BYで頻繁に使用するカラム
- 複合インデックスではカーディナリティの高いカラムを先頭に
- インデックスが増えるほどINSERT/UPDATE/DELETEが遅くなる点に注意
まとめ
インデックスはデータベース最適化の核心ツールですが、多ければ良いわけではありません。実際に実行されるクエリの実行計画を分析し、必要な箇所に戦略的に作成することが重要です。Erdmatesでテーブル構造をERDとして設計・管理しながら、最適なインデックス戦略を立てましょう。