Предупреждение о времени компиляции в Android Room о столбце во внешнем ключе не является частью индекса. Что это значит?

Я использую Android Persistence Library из компонентов Android Architecture, недавно объявленных в Google I/O. Кажется, что все работает, но я получаю следующую ошибку:

Предупреждение: столбец tagId ссылается на внешний ключ, но он не является частью индекс. Это может вызвать полное сканирование таблицы, когда родительская таблица поэтому вам настоятельно рекомендуется создать индекс, который охватывает этот столбец.

Моя база данных имеет 3 таблицы: Note, Tag и JoinNotesTags. Примечания к тегам - это отношения "многие ко многим", поэтому таблица JoinNotesTags обрабатывает отображение. Таблицы просты:

  • Note.id и Tag.id являются первичными ключами
  • JoinNotesTags.noteId ссылки Note.id
  • JoinNotesTags.tagId ссылки Tag.id

Ограничения внешнего ключа определяются в таблице JoinNotesTags. Для справки, вот инструкция CREATE TABLE для таблицы JoinNotesTags:

"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 включается в составной уникальный индекс вместе с noteId. Я подтвердил, что этот индекс также правильно определен в файле автоматической генерации json:

"CREATE UNIQUE INDEX `index_JoinNotesTags_noteId_tagId` 
    ON `JoinNotesTags` (`noteId`, `tagId`)"

Итак, мой вопрос: является ли это предупреждение просто ошибкой в ​​библиотеке комнат (все еще альфа-релиз), то есть во время анализа во время компиляции отсутствует тот факт, что tagId является частью этого составного индекса? Или у меня действительно есть проблема с индексацией, которую мне нужно решить, чтобы избежать полного сканирования таблицы?

Ответ 1

При изменении таблицы Tag для базы данных может потребоваться найти соответствующие строки в таблице JoinNotesTags. Чтобы быть эффективным, для требуется индекс в столбце tagId.

Ваш составной индекс не подходит для этого; из-за способа работы индексов, столбец (столбцы), подлежащие поиску, должен быть самым левым столбцом в индексе.

Вы должны добавить индекс только в столбец tagId. (Вы можете поменять порядок столбцов в составном индексе, но тогда у вас будет такая же проблема с noteId.)

Ответ 2

Вам нужно добавить индекс в столбцы для более быстрых запросов. Вот пример

@Entity(indices = {@Index("artist_id")})
public class Artist{
    @NonNull
    @PrimaryKey
    @ColumnInfo(name = "artist_id")
    public String id;
    public String name;
}

Ответ 3

когда в коде 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