複合インデックスを学ぶ
こんにちは。
rails初学者です。
この記事では、複合インデックスについて学んでいることを、記事にしてまとめていきます。
自分のための備忘録になります。
複合インデックスってなに?
複合インデックスとは、
複数のカラム(列)をセットでまとめて検索の高速化や重複チェックをするしくみ
のこと。
Railsでは、データベースに検索や並べ替えをお願いする時にインデックスがあると処理が速くなる。
単一カラム(1列)に対するインデックスの応用編のようなものが、複数のカラムをセットにした「複合インデックス」らしいです。
でも、実はこれがとても便利なようです。
TODOリストで考えてみる
たとえば、次のようなTODOアプリの場合
user_id | title | done | created_at |
---|---|---|---|
1 | ゴミ出し | false | 2025-06-01 10:00:00 |
1 | 洗濯する | true | 2025-06-01 08:00:00 |
2 | 宿題 | false | 2025-06-02 09:00:00 |
このとき、こんなことをしたいとする。
"あるユーザーの未完了タスクを、作成日時が新しい順に表示したい"
Railsではこんなコードになります:
todos = Todo.where(user_id: current_user.id, done: false).order(created_at: :desc)
このクエリを速くしたいとき、次のような複合インデックスを使う。
add_index :todos, [:user_id, :done, :created_at]
これによって、データベースは「user_id + done + created_at」の順番で効率よく絞り込み&並べ替えをしてくれるようになる。
知らなかった!!順番が超大事らしい。
複合インデックスは、登録したカラムの順番がとっても大切なようです。
add_index :todos, [:a, :b, :c]
この場合、以下のようなクエリには反映される。
where(a: ...)
where(a: ..., b: ...)
where(a: ..., b: ..., c: ...)
逆に、以下のようなクエリには反映されない。
-
where(b: ...)
← aが抜けてる -
where(c: ...)
← aもbも抜けてる
このルールは「左端プレフィックスルール」と呼ばれている。
一意制約にも使える
複合インデックスは、重複禁止(一意性)にも使えます。
たとえば、1人のユーザーが同じタイトルのTODOを2つ作れないようにするには...
add_index :todos, [:user_id, :title], unique: true
これで、「同じユーザーが『ゴミ出し』というタスクを2回登録」しようとしたらエラーになります。ユーザーが違えばよし。
まとめ
使いどころ | 例 |
---|---|
検索を速くしたい |
where(user_id: ..., done: false).order(created_at: :desc) に対して複合インデックス |
重複を防ぎたい |
[:user_id, :title] に一意制約付きインデックス |
データを守りたい | 同じ対象に対して重複した登録が起きないようにする |
複合インデックスは、アプリのパフォーマンスや信頼性をぐっと高めてくれる仕組み。
難しそうに見えて、やってることは「セットでまとめて見る」というだけ。
活用していきたいです。
初学者のため、間違えていたらすいません。