SQLの処理が遅いと感じたとき、多くの人が「サーバが遅いのでは?」と思いがちです。
しかし、実際の原因の多くは「インデックス(索引)」の使い方にあります。
この記事では、インデックスの基本構造から、実際のチューニング手法までを体系的に解説します。
1. インデックスとは?
インデックスとは、データベースが**検索を高速化するために作成する“索引”**のことです。
書籍の巻末索引のように、「この値はどこにあるか」を素早く見つけるための目次のような仕組みです。
🔹 例:インデックスなしの検索
このとき、インデックスが無ければ、データベースは全件を1件ずつ確認します(フルスキャン)。
🔹 例:インデックスありの検索
これにより、該当レコードを索引経由で一瞬で特定できるようになります。
2. インデックスの仕組みを理解する
🧩 B-treeインデックス
ほとんどのRDBMS(Oracle、MySQL、PostgreSQLなど)で採用されている構造です。
値が昇順に整理され、2分探索のように効率的に検索できます。
例えば「70」を探すとき、50より大きいので右に進み、次に70を発見します。
わずか2ステップで到達できるため、フルスキャンに比べて圧倒的に速いのです。
🧩 ビットマップインデックス(Oracleなど)
主に**値の種類が少ないカラム(性別、ステータスなど)**に有効です。
各値に対応するレコードのビットマップを管理することで、AND/OR検索が高速化します。
3. どんなカラムにインデックスを貼るべきか?
✅ 有効なケース
-
WHERE句で頻繁に検索される列 -
JOIN条件に使われる列 -
ORDER BYやGROUP BYの対象列 -
外部キー(
FOREIGN KEY)列
🚫 不向きなケース
-
データ件数が極端に少ない列(例:性別など)
-
更新頻度が高い列(INSERT/UPDATEが多いと再構築コストが増大)
-
テーブル全件を常に取得するクエリ
4. 実行計画で確認する
SQLの速度改善は、**「インデックスが使われているか」**を確認することが第一歩です。
結果例(MySQLの場合)
| type | key | rows | Extra |
|---|---|---|---|
| ref | idx_users_email | 1 | Using index |
「Using index」と表示されていれば、インデックスが利用されています。
逆に「ALL」となっている場合はフルスキャンです。
5. インデックスを使った高速化テクニック
🌟 複合インデックス(複数列)
複数の列を組み合わせた検索で効果を発揮します。
ただし、先頭の列が条件に含まれないと使われない点に注意が必要です。
例:
🌟 カバリングインデックス(Covering Index)
インデックスに必要な列すべてを含めることで、テーブルアクセスをスキップできます。
テーブルを参照せずにインデックスだけで完結するため、極めて高速です。
🌟 LIKE検索の最適化
前方一致(Yui%)はインデックスが有効ですが、
のような部分一致はインデックス無効です。
対策としては、**全文検索エンジン(MySQLのFULLTEXT、PostgreSQLのGIN/GiST)**を使う方法があります。
6. 注意点:インデックスの弊害
インデックスは便利ですが、万能ではありません。
特に以下の点には注意が必要です。
| リスク | 説明 |
|---|---|
| 更新コスト増大 | INSERTやUPDATE時にインデックスも更新されるため、処理が重くなる |
| ストレージ消費 | 大規模テーブルに多くのインデックスを張ると、容量が急増 |
| メンテナンス負荷 | 不要なインデックスを放置すると、統計情報がずれて性能が劣化 |
🧹 定期的に ANALYZE TABLE や REBUILD INDEX を実施して、統計情報を更新しましょう。
7. 実践チューニング例
✏️ 例1:検索が遅いクエリ
🩹 改善策
✅ 実行計画の変化
-
変更前:
type = ALL(フルスキャン) -
変更後:
type = ref(インデックス参照)
実行時間が数秒 → 数ミリ秒まで短縮されることもあります。
まとめ
| ポイント | 内容 |
|---|---|
| インデックスとは | データ検索を高速化するための“索引” |
| 構造 | B-treeが主流。ビットマップは限定用途 |
| 効果的な付与 | 検索条件、JOIN、GROUP BY、ORDER BY列 |
| 落とし穴 | 更新負荷、容量増加、部分一致非対応 |
| 確認方法 | EXPLAINで実行計画を必ずチェック |
🚀 結論
インデックスを理解すれば、SQLの速度は10倍以上高速化することも珍しくありません。
なんとなく作るのではなく、「どう検索されるか」を意識して設計することが重要です。
