Подтвердить что ты не робот

Полнотекстовое индексирование вяло. Поиск альтернатив

У меня есть таблица, в которой я создал полнотекстовый каталог. В таблице всего 6000 строк. Я добавил два индекса в индекс. Первым можно считать уникальный идентификатор сортировок, а второй можно считать содержимым для этого элемента (в моей таблице еще 11 столбцов, которые не являются частью полнотекстового каталога). Ниже приведен пример нескольких строк:

TABLE: data_variables
ROW    unique_id    label
1      A100d1       Personal preference of online shopping sites
2      A100d2       Shopping behaviors for adults in household

В моем веб-приложении на переднем конце у меня есть текстовое поле, которое пользователь может ввести, чтобы получить список элементов, которые соответствуют тем терминам, которые они ищут в столбцах UNIQUE ID или LABEL. Так, например, если пользователь набрал sho или a100, тогда список будет заполнен обеими строками выше. Если они набрали behav, тогда список будет заполнен только следующей строкой 2.

Это выполняется с помощью запроса Ajax на каждом keyup. PHP вызывает хранимую процедуру на SQL-сервере, которая выглядит следующим образом:

SELECT TOP 50 dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         (CONTAINS((dv.unique_id, dv.label), @search))

(@search - это текст пользователя, который передается в хранимую процедуру.)

Я заметил, что это становится довольно медлительным, особенно когда я не использовал TOP 50 в запросе.

Я ищу способ ускорить это либо непосредственно на SQL Server, либо отказаться от идеи полнотекстового индексирования и использовать jQuery для поиска по массиву элементов, доступных для поиска на стороне клиента. Я немного посмотрел в материал jQuery AutoComplete и некоторые другие плагины jQuery для автозаполнения, но еще не пытался что-то макетировать. Это было бы моим следующим шагом, но я хотел сначала проверить здесь, чтобы узнать, какой совет я получу.

Спасибо заранее.

4b9b3361

Ответ 1

Несколько предложений, основанных на факте, что у вас есть только 6000 строк, поэтому база данных должна есть это живое.

а. Попробуйте использовать оператор Like, на всякий случай это поможет. Не ожидая этого, но довольно тривиально, чтобы попробовать. Здесь есть что-то еще, чтобы вы обнаружили, что это медленно, учитывая эти небольшие объемы.

В. можете ли вы кэшировать запросы заранее? С 6000 строк, вероятно, всего 36 * 36 комбинаций из 2-х символьных запросов, которые не должны иметь практически никакой памяти и сохранять базу данных в любой работе.

С. Перемещение выделения на клиента - хорошая идея, зависит от того, насколько велики 6000 строк в целом, а также задержка в сети для отдельных поисков.

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

Ответ 2

Я бы посоветовал против LIKE, если вы не используете линейный индекс (слева направо), и вы делаете такие запросы, как LIKE 'work%'. Если вы делаете что-то вроде LIKE '%word%', регулярный индекс не поможет вам. Обычно вы хотите использовать полнотекстовый индекс, если хотите найти слова внутри абзаца.

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

Некоторые параметры Sphinx, Solr, и elasticsearch, просто чтобы назвать несколько. Я бы не сказал, что любой из этих вариантов лучше, чем другой. Конечно, есть плюсы и минусы:

  • Какие данные у вас есть?
  • Какая языковая поддержка поддерживает эти решения?
  • Какие механизмы баз данных поддерживают эти решения?

Лучшее, что вы можете сделать, это сравнить эти решения с вашими существующими данными. Тестирование каждого отдельного компонента (модульное тестирование) может помочь вам определить реальные проблемы и помочь найти полезные решения.

Ответ 3

У меня была такая же проблема, и я пошел на решение LIKE. Я обнаружил, что оператор или оператор слишком облагаются налогом и делят запрос на два выбора с объединением всех (самый быстрый, и в моем сценарии невозможно было найти тот же текст в столбце индекса и данных).

Ваш будет как

SELECT TOP 50 from (
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.unique_id like '%'[email protected]+'%'
UNION ALL
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.label like '%'[email protected]+'%' 
)

О!! И протестируйте производительность в SQL Server, а не в Интернете!

Ответ 4

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

Посмотрите Apache Solr - лучшая полнотекстовая поисковая система в данный момент.

Вы можете просто периодически индексировать данные своей базы данных и использовать solr в качестве поисковой системы, он обеспечивает простой ajax api и может быть запрошен непосредственно из интерфейса.

Ответ 5

Если вам действительно нужна производительность... вы можете захотеть взглянуть; FTS3 и FTS4...

snip... с другого форума...

Например, если каждый из документов 517430 в "наборе данных электронной почты Enron" вставлен как в таблицу FTS, так и в обычную таблицу SQLite, созданную с использованием следующего SQL script:

код: CREATE VIRTUAL TABLE enrondata1 ИСПОЛЬЗОВАНИЕ fts3 (content TEXT);/* Таблица FTS3/ CREATE TABLE enrondata2 (content TEXT);/Обычная таблица */ Затем один из двух запросов ниже может быть выполнен, чтобы найти количество документов в базе данных, содержащих слово "linux" (351). Используя конфигурацию аппаратного обеспечения настольного ПК, запрос в таблице FTS3 возвращается примерно через 0,03 секунды против 22,5 для запроса обычной таблицы.

см...

http://www.sqlite.org/fts3.html