Как sqlite выбирает индекс при запросе записей? - PullRequest
0 голосов
/ 03 июля 2018
  1. Фон

    Я разработчик для iOS, и мы используем CoreData, которая использует базу данных sqlite для хранения данных на диске в нашем проекте. За несколько дней до этого один из наших пользователей сказал, что его интерфейс в некоторых случаях не свободно используется при использовании нашего приложения с версией 2.9.9. После некоторых усилий мы наконец обнаружили, что это связано с плохой эффективностью при запросе записей из sqlite. Но после обновления до последней версии 3.0.6 проблема исчезла.

  2. Анализ

    (1) при запросе записей из sqlite запрос SQL будет

    'ВЫБРАТЬ * ИЗ ZAPIOBJECT, ГДЕ ZAPIOBJECTID = "xxx" И Z_ENT == 34'

    В версии 2.9.9 нашего приложения схема таблицы «ZAPIOBJECT» sqlite показывает

    'CREATE INDEX ZAPIOBJECT_Z_ENT_INDEX ON ZAPIOBJECT (Z_ENT);'

    'CREATE INDEX ZAPIOBJECT_ZAPIOBJECTID_INDEX ON ZAPIOBJECT (ZAPIOBJECTID);'

    и план запроса показывает

    '0 0 0 ПОИСК ТАБЛИЦЫ ZAPIOBJECT AS t0 ИСПОЛЬЗОВАНИЕ ИНДЕКСА ZAPIOBJECT_Z_ENT_INDEX (Z_ENT =?) ’

    , который использует менее эффективный индекс "Z_ENT" ( стоимость ~ 4 с для 1 строки ).

    (2) В версии 3.0.6 нашего приложения запрос SQL такой же:

    'ВЫБРАТЬ * ИЗ ZAPIOBJECT, ГДЕ ZAPIOBJECTID = "xxx" И Z_ENT == 34'

    но схема таблицы "ZAPIOBJECT" sqlite показывает:

    ‘CREATE INDEX ZAPIOBJECT_Z_ENT_INDEX ON ZAPIOBJECT (Z_ENT);’

    ‘CREATE INDEX Z_APIObject_apiObjectID ON ZAPIOBJECT (ZAPIOBJECTID COLLATE BINARY ASC);’

    и план запроса показывает

    ‘0 0 0 ПОИСК ТАБЛИЦЫ ZAPIOBJECT КАК t0 ИСПОЛЬЗОВАТЬ ИНДЕКС Z_APIObject_apiObjectID (ZAPIOBJECTID =?)’

    , который использует более эффективный индекс "ZAPIOBJECTID" ( стоимость ~ 0,03 с за 1 ро w).

    (3) общее количество записей в таблице «ZAPIOBJECT» составляет около 130000, и мы создаем индекс «ZAPIOBJECTID», отличное число которого превышает 90000, в то время как индекс «Z_ENT», отличное число которого составляет только 20 создан CoreData.

    (4) версии sqlites в двух версиях нашего приложения совпадают 3.8.8.3.

  3. Вопросы

    (1) Как sqlite выбрать индекс при запросе записей? В документе Планирование запросов я узнаю, что sqlite сам выберет лучшие алгоритмы, однако в нашем случае выбор другого индекса может привести к очевидной эффективности. Разница между созданием ZAPIOBJECTID в двух версиях нашего приложения приводит к другому индексу, принятому sqlite?

    (2) Похоже, что те пользователи, чья версия системы ниже iOS 11, столкнулись бы с этой проблемой, так как мы можем решить эту проблему для них? Можем ли мы установить «ZAPIOBJECTID» в качестве назначенного индекса с помощью CoreData API?

1 Ответ

0 голосов
/ 04 июля 2018

SQLite использует индекс, который приводит к наименьшему количеству предполагаемых операций ввода-вывода. Детали этой оценки меняются в каждой версии.

См. Контрольный список , позволяющий избежать или исправить проблемы с планировщиком запросов .

...