SQLのINDEXとは?検索を高速化する仕組みをやさしく解説
INDEXとは何か
INDEX(インデックス)は、本の巻末にある「索引」と同じ役割を果たす仕組みです。分厚い専門書で特定の用語を探すとき、最初のページから1ページずつめくるのではなく、巻末の索引でページ番号を調べてから該当ページを直接開きますよね。データベースのINDEXも同じで、テーブルの特定のカラムに「索引」を作っておくことで、目的のデータをすばやく見つけられるようになります。
INDEXがないとどうなるか
INDEXが貼られていないカラムを条件に検索すると、データベースはテーブルの先頭から最後まで全行を1件ずつ確認します。これを「フルスキャン(全表走査)」と呼びます。
-- emailにINDEXがない場合、全件をスキャンして探す
SELECT * FROM users WHERE email = 'tanaka@example.com';数十件程度のテーブルならフルスキャンでも一瞬ですが、100万件・1000万件規模になると、検索のたびに全件をなめる処理は致命的に遅くなります。INDEXは、このフルスキャンを避けるための仕組みです。
CREATE INDEXの書き方
INDEXを作成するにはCREATE INDEX文を使います。
-- usersテーブルのemailカラムにINDEXを作成
CREATE INDEX idx_users_email ON users (email);
-- 不要になったら削除できる
DROP INDEX idx_users_email;一度作成すれば、以降その日カラムを条件にした検索は自動的にINDEXを経由して高速化されます。アプリ側のSQL文を書き換える必要はありません。
どのカラムにINDEXを貼るべきか
INDEXは「とりあえず全部のカラムに貼っておく」ものではありません。効果が大きいのは主に以下のようなカラムです。
- WHERE句で頻繁に条件指定されるカラム(例:
email、status) - JOINの結合条件に使われるカラム(外部キーなど)
- ORDER BYで並び替えによく使われるカラム
- 値の種類が多く、絞り込み効果が高いカラム(性別のような値が2〜3種類しかないカラムは効果が薄い)
複合INDEX(複数カラムのINDEX)
2つ以上のカラムを組み合わせたINDEXも作成できます。
-- departmentとsalaryを組み合わせたINDEX
CREATE INDEX idx_emp_dept_salary ON employees (department, salary);
-- このINDEXが効果的に使われるクエリ
SELECT * FROM employees
WHERE department = '営業部' AND salary >= 300000;複合INDEXは左側のカラムから順番に使われるという性質があります。上の例ではdepartmentだけの検索にも使えますが、salaryだけの検索には使われません。作成する順番が重要です。
INDEXのデメリット
INDEXは検索を速くする一方で、タダではありません。主なデメリットは次の2つです。
- 書き込みが遅くなる:INSERT・UPDATE・DELETEのたびに、テーブル本体だけでなくINDEXも更新する必要があるため、書き込み処理に負荷がかかります
- ディスク容量を消費する:INDEXはデータの複製に近い構造を持つため、テーブルとは別に保存領域が必要です
そのため「検索頻度が高く、書き込み頻度が低いカラム」にINDEXを絞って作成するのが基本的な考え方です。
EXPLAINでINDEXの効果を確認する
実際にINDEXが使われているかどうかは、EXPLAIN文で確認できます。
EXPLAIN SELECT * FROM users WHERE email = 'tanaka@example.com';実行計画の中に「Index Scan」のような表示が出ればINDEXが使われており、「Seq Scan」と表示されればフルスキャンが行われています。パフォーマンスチューニングの第一歩として、まずは自分のクエリがどちらで動いているか確認してみましょう。
まとめ
- INDEXは本の索引と同じ、検索を高速化するための仕組み
- INDEXがないと全件をなめる「フルスキャン」が発生する
CREATE INDEXで作成、DROP INDEXで削除できる- WHERE・JOIN・ORDER BYで頻繁に使うカラムに効果的
- 書き込み負荷とディスク容量というトレードオフがある
EXPLAINで実際に使われているか確認できる
基礎を固めてからパフォーマンスを学ぼう
INDEXの効果を理解するには、まずSELECT・WHERE・JOINの基礎が欠かせません。SQLLearnで無料の練習問題に挑戦してみましょう。
無料で今すぐ練習する →