0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails初学者】はじめての複合インデックス

Posted at

複合インデックスを学ぶ

こんにちは。
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] に一意制約付きインデックス
データを守りたい 同じ対象に対して重複した登録が起きないようにする

複合インデックスは、アプリのパフォーマンスや信頼性をぐっと高めてくれる仕組み。
難しそうに見えて、やってることは「セットでまとめて見る」というだけ。
活用していきたいです。

初学者のため、間違えていたらすいません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?