SQLite: должен ли LIKE searchstr% использовать индекс - PullRequest
18 голосов
/ 21 декабря 2011

У меня есть БД с несколькими полями

word_id — INTEGER PRIMARY_KEY
word — TEXT
...

.. и ~ 150 тыс. Строк.

Поскольку это словарь, я ищу слово с маской 'search_string%'используя как.Раньше он работал просто отлично, занимая 15 мсек, чтобы найти подходящие строки.Таблица имеет индекс для поля 'word'.Недавно я изменил таблицу (некоторые поля этой таблицы находятся вне области видимости), и что-то произошло - для выполнения запроса требуется 400 мс, так что я понимаю, что теперь он не может использовать индекс.Простой запрос с = вместо аналогичного показывает результат 10 мс.У кого-то есть идея, что здесь происходит?

1 Ответ

28 голосов
/ 21 декабря 2011

В этом случае нельзя безопасно использовать индекс.Наивная реализация преобразует это:

... WHERE word LIKE 'search_string%'

в

... WHERE word >= 'search_string' AND word < 'search_strinh'

, увеличивая последний символ строки поиска.Операторы «больше» и «меньше» могут использовать индекс, а LIKE - нет.

К сожалению, в общем случае это не сработает.Оператор LIKE нечувствителен к регистру, что означает, что 'a' LIKE 'A' имеет значение true.Вышеупомянутое преобразование будет разбивать любую строку поиска заглавными буквами.

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

  1. Используйте последовательность сортировки NOCASE для индекса, который охватывает это конкретное поле.
  2. Измените поведение программы оператора LIKE-в целом, запустив PRAGMA case_sensitive_like = ON;

Любое из этих действий позволит SQLite прозрачно выполнить вышеуказанное преобразование для вас;вы просто продолжаете использовать LIKE как всегда, и SQLite перепишет базовый запрос для использования индекса.

Подробнее о "Оптимизации LIKE" можно прочитать на странице Обзор SQLite Query Optimizer .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...