Я разрабатываю приложение для 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];
Есть ли хороший способ повысить производительность поиска части строки во всех столбцах?
Спасибо и добрые пожелания,
Даниил
3 ответа
Вам нужен полнотекстовый поиск, который SQLite изначально не поддерживает. У меня нет опыта работы со сторонней поддержкой, но на основе результатов есть несколько вариантов.
Вы сами ответили на свой вопрос: сделайте индекс по всем четырем столбцам. И измерьте разницу в размерах. Учитывая емкость памяти iPhone, вы, вероятно, не сбалансированы, пытаясь уменьшить объем памяти.
Эмпирическое правило производительности SQLite - не выполнять неиндексированный запрос.
Вы можете увидеть, что на самом деле делает SQLite, создав свою базу данных на Mac, используя ту же схему и EXPLAIN QUERY PLAN. (Также есть EXPLAIN, более подробный, но менее очевидный.)
Вы можете создать отдельную таблицу с двумя столбцами: строка шаблона и значение ключа (которое используется для ссылки на ваши таблицы данных). Назовем эту таблицу search_index.
Затем при любом изменении записей таблицы данных вы обновляете таблицу search_index:
- удалить строки с ключами измененных строк таблицы данных
- для каждого столбца в таблице данных используйте первые X символов данных и добавьте их в search_index с ключом
Вы можете сами проработать детали, но таким образом вы просто создадите свой собственный (частичный) поисковый индекс.
При запросе вы можете использовать до X символов для поиска только в таблице search_index. Если пользователь вводит более X символов, у вас, по крайней мере, есть ограниченный набор строк таблицы данных для поиска. Таким образом, вы можете легко выполнять поиск в этих 60k строках.
Найдите подходящее значение для X, чтобы сбалансировать требования к хранилищу, удобство использования и производительность.
РЕДАКТИРОВАТЬ : похоже, вы не хотите искать только в начале слова? Что ж, тогда вы должны не просто использовать «первые X символов», но вы должны разбить данные на отдельные слова и использовать полные слова в search_index. Хотя на практике у вас по-прежнему будет примерно четверть требований к хранению индекса по сравнению с указанием индекса для всех столбцов. Так что еще неплохо создать свой собственный "search_index".
Похожие вопросы
Связанные вопросы
Новые вопросы
iphone
НЕ ИСПОЛЬЗУЙТЕ этот тег, если вы не обращаетесь конкретно к iPhone и / или iPod touch от Apple. Для вопросов, не зависящих от оборудования, используйте тег [ios]. Больше тегов, которые нужно рассмотреть, это [xcode] (но только если вопрос касается самой IDE), [swift], [target-c] или [cocoa-touch] (но не [cocoa]). Пожалуйста, воздержитесь от вопросов, касающихся iTunes App Store или iTunes Connect. Если вы используете C #, пометьте [mono].