Google I/Oで最近発表されたAndroid Architecture ComponentsからAndroidのRoom Persistence Libraryを使用しています。物事は機能しているようですが、次のエラーが表示されます。
警告:tagId列は外部キーを参照していますが、インデックスの一部ではありません。これにより、親テーブルが変更されるたびに全テーブルスキャンがトリガーされる可能性があるため、この列をカバーするインデックスを作成することを強くお勧めします。
データベースには、Note
、Tag
、JoinNotesTags
の3つのテーブルがあります。タグへのメモは多対多の関係であるため、マッピングを処理するJoinNotesTagsテーブルです。テーブルは簡単です。
Note.id
とTag.id
は両方とも主キーですJoinNotesTags.noteId
参照Note.id
JoinNotesTags.tagId
参照Tag.id
外部キー制約は、JoinNotesTags
テーブルで定義されます。参考のために、JoinNotesTags
テーブルのCREATE TABLE
ステートメントを以下に示します。
"CREATE TABLE IF NOT EXISTS `JoinNotesTags` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`noteId` INTEGER,
`tagId` INTEGER,
FOREIGN KEY(`noteId`) REFERENCES `Note`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
FOREIGN KEY(`tagId`) REFERENCES `Tag`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
)"
そして、そのクラスに対応する@Entity
アノテーションは次のとおりです。
@Entity(
indices = arrayOf(Index(value = *arrayOf("noteId", "tagId"), unique = true)),
foreignKeys = arrayOf(
ForeignKey(
entity = Note::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("noteId"),
onDelete = ForeignKey.CASCADE),
ForeignKey(
entity = Tag::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("tagId"))
)
)
@Entity
アノテーションからわかるように、tagId
isは、noteId
とともに複合一意インデックスに含まれています。このインデックスは、自動生成されたjsonスキーマファイルでも正しく定義されていることを確認しました。
"CREATE UNIQUE INDEX `index_JoinNotesTags_noteId_tagId`
ON `JoinNotesTags` (`noteId`, `tagId`)"
だから、私の質問:この警告は(まだアルファリリースの)ルームライブラリのバグですか?つまり、コンパイル時の分析では、tagId
がこの複合インデックスの一部であるという事実が欠落していますか?または、テーブル全体のスキャンを回避するために解決する必要があるインデックス作成の問題が本当にありますか?
Tag
テーブルを変更すると、データベースはJoinNotesTags
テーブル内の対応する行を検索する必要がある場合があります。効率的にするために、これはtagId
列の インデックスが必要 です。
複合インデックスはそのためには役立ちません。 インデックスの動作方法 のため、検索する列はインデックスの左端の列でなければなりません。
tagId
列のみにインデックスを追加する必要があります。 (複合インデックスの列の順序を入れ替えることはできますが、noteId
でも同じ問題が発生します。)
クエリを高速化するには、列にインデックスを追加する必要があります
@Entity(indices = {@Index("artist_id")})
public class Artist{
@NonNull
@PrimaryKey
@ColumnInfo(name = "artist_id")
public String id;
public String name;
}
kotlinコードの場合:
前
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id")
var questionId: Long
後
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id", index = true) //just add index = true
var questionId: Long