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?

Roomで複合主キーを使っている場合にprimaryKeysの先頭のカラムにIndexは不要

Last updated at Posted at 2026-01-26

SQLite や MySQL を使っている人的には常識かもしれないけど備忘録のためにメモ。


Room で以下のような複合主キー付きのテーブルがあったとして、

@Entity(
    primaryKeys = ["hoge_id", "fuga_id"],
)
data class HogeFugaCrossRef(
    @ColumnInfo(name = "hoge_id")
    val hogeId: String,
    @ColumnInfo(name = "fuga_id")
    val fugaId: String,
)

primaryKeys の先頭にある hoge_id は複合主キーの場合に自動で作られる Index で検索可能なので、Index の設定は不要。
EXPLAIN すると、SEARCH HogeFugaCrossRef USING INDEX sqlite_autoindex_HogeFugaCrossRef_1 (hoge_id=?) となる。

これは SQLite や MySQL の仕様で左側にあるカラムを使うためにこうなっている。

先頭以外のカラムで検索をかけることがある場合には Index の設定が必要。

@Entity(
    primaryKeys = ["hoge_id", "fuga_id"],
    indices = [
        Index(value = ["fuga_id"]),
    ],
)
data class HogeFugaCrossRef(
    @ColumnInfo(name = "hoge_id")
    val hogeId: String,
    @ColumnInfo(name = "fuga_id")
    val fugaId: String,
)

fuga_id に対して検索するクエリの EXPLAIN すると、SEARCH HogeFugaCrossRef USING INDEX index_HogeFugaCrossRef_fuga_id (fuga_id=?) となる。ちなみに Index がないと SCAN HogeFugaCrossRef になる。

primaryKeys の配列内を入れ替えると複合主キーの設定で作られる Index が変わるので注意が必要。

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?