Оптимизация в SQLite

Есть необходимость ускорения поиска в БД SQLite в одном проекте на iPhone.

База большая, более миллиона записей. Есть несколько текстовых полей varchar, по которым ведется поиск. Информация на русском языке UTF8.

В настоящий момент используется LIKE + пользовательская функция перевода в нижний регистр. Проблема в том, что в этом случае нельзя использовать индекс. В итоге запрос выполняется почти минуту.

Что можете посоветовать для ускорения?
  • Вопрос задан
  • 9503 просмотра
Пригласить эксперта
Ответы на вопрос 3
@Krovosos
Если поиск ведется по условию 'XXX%', то индекс использовать можно.

Если нужен полнотекстовый поиск, то смотреть здесь
Ответ написан
@Krovosos
LIKE не подхватывает, потому что есть тонкости. Про них можно почитать здесь.

Вкратце:
1) столбец в таблице обязан иметь тип TEXT:

foo(bar TEXT) — хорошо, foo (bar) — плохо

2) по умолчанию: LIKE регистронезависим, а COLLATION (т.е. способ сравнения данных) используется BINARY, то есть обычное посимвольное совпадение = регистрозависим.

Поэтому нужно либо включить режим case-sensitive для LIKE командой

PRAGMA case_sensitive_like = 1;

Либо в индексе указать нужный тип COLLATION:

CREATE INDEX idx ON foo (name COLLATE NOCASE);

3) LIKE должен быть записан как <СТОЛБЕЦ> LIKE «XXX%»

Т.е. слева — столбец, справа — строковый литерал, который _не начинается_ на wildcard.

Проверил вариант с case_sensitive_like = 1; индекс используется.
Ответ написан
FloppyFormator
@FloppyFormator
Самый хороший способ — это заставить SQLite работать с русским языком по-человечески. Т. к. отсутствие поддержки ещё выползет боком в разных других местах. Но если это невозможно, можно продублировать все поля, по которым ведётся поиск, и хранить в них текст в нижнем регистре. Ну и программно следить за тем, чтобы значения в них соответствовали исходным полям.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы