Я разрабатываю приложение для Iphone, в котором пользователь вводит любую строку в строку поиска и нажимает кнопку поиска. После этого должен появиться список результатов.

В моем SQLite есть четыре столбца a, b, c, d. Допустим, у них есть следующие значения:

Dataset 1:
a: code1
b: report1
c: description1_1
d: description1_2

Dataset 2:
a: code2
b: report2
c: description2_1
d: description2_2

Таким образом, если пользователь вводит значение: «1_1», тогда будет выбран первый набор данных из-за столбца c. Если пользователь вводит значение: «отчет», то будут выбраны первый и второй набор данных.

Поскольку я использую базу данных с почти 60 000 наборов данных, поиск части строки действительно убивает производительность.

Установка индекса для всех 4 столбцов сделает размер базы данных SQLite слишком большим. Так что я вообще не использовал индекс.

Мое заявление о выборе выглядит так:

NSString *sql = [NSString stringWithFormat:@"SELECT * FROM scode WHERE a LIKE '%@%@%@' OR c LIKE '%@%@%@' OR d LIKE '%@%@%@'", wildcard, searchBar.text, wildcard, wildcard, searchBar.text, wildcard, wildcard, searchBar.text, wildcard, wildcard, searchBar.text, wildcard];

Есть ли хороший способ повысить производительность поиска части строки во всех столбцах?

Спасибо и добрые пожелания,

Даниил

4
Daniel 2 Янв 2010 в 02:15

3 ответа

Лучший ответ

Вам нужен полнотекстовый поиск, который SQLite изначально не поддерживает. У меня нет опыта работы со сторонней поддержкой, но на основе результатов есть несколько вариантов.

2
OMG Ponies 2 Янв 2010 в 02:22
Полнотекстовый поиск - это определенно то, что ему нужно, один аспект этого меня смущает. В Sqlite есть FTS3, но он не включен сейчас, не так ли?
 – 
Steven Fisher
8 Янв 2010 в 21:29

Вы сами ответили на свой вопрос: сделайте индекс по всем четырем столбцам. И измерьте разницу в размерах. Учитывая емкость памяти iPhone, вы, вероятно, не сбалансированы, пытаясь уменьшить объем памяти.

Эмпирическое правило производительности SQLite - не выполнять неиндексированный запрос.

Вы можете увидеть, что на самом деле делает SQLite, создав свою базу данных на Mac, используя ту же схему и EXPLAIN QUERY PLAN. (Также есть EXPLAIN, более подробный, но менее очевидный.)

1
Steven Fisher 4 Янв 2010 в 02:35

Вы можете создать отдельную таблицу с двумя столбцами: строка шаблона и значение ключа (которое используется для ссылки на ваши таблицы данных). Назовем эту таблицу search_index.

Затем при любом изменении записей таблицы данных вы обновляете таблицу search_index:

  1. удалить строки с ключами измененных строк таблицы данных
  2. для каждого столбца в таблице данных используйте первые X символов данных и добавьте их в search_index с ключом

Вы можете сами проработать детали, но таким образом вы просто создадите свой собственный (частичный) поисковый индекс.

При запросе вы можете использовать до X символов для поиска только в таблице search_index. Если пользователь вводит более X символов, у вас, по крайней мере, есть ограниченный набор строк таблицы данных для поиска. Таким образом, вы можете легко выполнять поиск в этих 60k строках.

Найдите подходящее значение для X, чтобы сбалансировать требования к хранилищу, удобство использования и производительность.

РЕДАКТИРОВАТЬ : похоже, вы не хотите искать только в начале слова? Что ж, тогда вы должны не просто использовать «первые X символов», но вы должны разбить данные на отдельные слова и использовать полные слова в search_index. Хотя на практике у вас по-прежнему будет примерно четверть требований к хранению индекса по сравнению с указанием индекса для всех столбцов. Так что еще неплохо создать свой собственный "search_index".

0
Frunsi 4 Янв 2010 в 02:56