Что такое полнотекстовый поиск против LIKE

Я только что прочитал пост с упоминанием "полнотекстового поиска" в SQL.

Мне просто интересно, в чем разница между FTS и LIKE. Я прочитал пару статей, но не смог найти ничего, что бы объяснило это хорошо.

6 ответов

Решение

В общем, существует компромисс между "точностью" и "отзывом". Высокая точность означает, что представлено меньше не относящихся к делу результатов (без ложных срабатываний), в то время как высокая степень отзыва означает, что меньше релевантных результатов отсутствуют (без ложных отрицательных результатов). Использование оператора LIKE дает вам 100% точность без каких-либо уступок для отзыва. Функция полнотекстового поиска дает вам большую гибкость, чтобы настроить точность для лучшего отзыва.

В большинстве реализаций полнотекстового поиска используется "инвертированный индекс". Это индекс, где ключи - это отдельные термины, а связанные значения - это наборы записей, которые содержат термин. Полнотекстовый поиск оптимизирован для вычисления пересечения, объединения и т. Д. Этих наборов записей и, как правило, предоставляет алгоритм ранжирования для количественной оценки соответствия данной записи поисковым ключевым словам.

Оператор SQL LIKE может быть крайне неэффективным. Если вы примените его к неиндексированному столбцу, для поиска совпадений будет использоваться полное сканирование (как и любой запрос к неиндексированному полю). Если столбец проиндексирован, сопоставление может быть выполнено с ключами индекса, но с гораздо меньшей эффективностью, чем большинство поисков индекса. В худшем случае шаблон LIKE будет иметь подстановочные знаки, которые требуют проверки каждого ключа индекса. Напротив, во многих системах поиска информации можно включить поддержку ведущих символов подстановки, предварительно скомпилировав деревья суффиксов в выбранных полях.

Другие особенности, типичные для полнотекстового поиска:

  • лексический анализ или токенизация - разбивка блока неструктурированного текста на отдельные слова, фразы и специальные токены
  • морфологический анализ или определение - сведение вариаций данного слова в один индексный термин; например, относясь к "мышам" и "мышам" или "электрификации" и "электрическим" как к одному и тому же слову
  • ранжирование - измерение сходства соответствующей записи со строкой запроса

FTS включает в себя индексацию отдельных слов в текстовом поле, чтобы сделать поиск по множеству записей быстрым. Использование LIKE по-прежнему требует от вас поиска строки (линейной или подобной) в пределах поля.

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

Также из этого ТА ответа:

Есть несколько преимуществ для полнотекстового поиска.

Индексация:

Что-то вроде:

WHERE Foo LIKE '%Bar';

Невозможно воспользоваться индексом. Он должен посмотреть на каждую строку и посмотреть, соответствует ли он. Полнотекстовый индекс, однако, может. Фактически, полнотекстовые индексы могут предложить гораздо большую гибкость с точки зрения порядка соответствия слов, насколько близко эти слова находятся вместе и т. Д.

Сдерживание:

Полнотекстовый поиск может использовать слова. Если вы ищете для запуска, вы можете получить результаты для "побежал" или "работает". Большинство полнотекстовых движков имеют словари на разных языках.

Взвешенные результаты:

Полнотекстовый индекс может включать несколько столбцов. Например, вы можете искать "персиковый пирог", и индекс может включать заголовок, ключевые слова и текст. Результаты, соответствующие названию, могут быть взвешены выше, как более релевантные, и могут быть отсортированы так, чтобы отображаться в верхней части.

Недостатки:

Полнотекстовый индекс потенциально может быть огромным, во много раз больше, чем стандартный индекс B-TREE. По этой причине многие хостинговые провайдеры, которые предлагают экземпляры базы данных, отключают эту функцию или, по крайней мере, взимают дополнительную плату за нее. Например, в последний раз, когда я проверял, Windows Azure не поддерживает полнотекстовые запросы.

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

В Like используются только символы подстановки, и они не такие мощные.

Полный текст позволяет выполнять более сложный поиск, включая "И" или "Не", даже похожие результаты звучания (SOUNDEX) и многие другие элементы.

Я бы начал смотреть на SQL CONTAINS() FREETEXT() и связанные с ним элементы полнотекстового поиска, чтобы лучше понять, что доступно.

Настоящая разница заключается в методологиях сканирования. Для полнотекстового поиска слова (термины) используются в качестве ключей хеширования, каждое из которых связано с массивом документов, в которых появляются ключи (термины). Это выглядит так:

Document sets = {d1, d2, d3, d4, ... dn}
Term sets = {t1, t2, t3, .. tn}

Теперь матрица терминов документа (член термина какого документа) может быть представлена ​​как:

t1 -> {d1, d5, d9,.. dn}
t2 -> {d11, d50, d2,.. dn}
t3 -> {d23, d67, d34,.. dn}
:
tn -> {d90, d87, d57,.. dn}

Когда приходит запрос с просьбой "Получить мне все документы, содержащие слово / термин t1" - тогда набор документов {d1, d5, d9,.. dn} возвращается.

Вы можете взломать ненормализованную схему таблицы для хранения документов - каждая строка в таблице MySQL будет рассматриваться как "документ", а столбец TEXT может содержать абзац и т. Д. Инвертированный индекс будет содержать термины в качестве ключей хеш-функции и идентификаторов строк. как идентификаторы документа.

Помните, что этот SQL-запрос будет иметь более или менее высокую производительность O(1). Запрос не будет зависеть от

  1. Количество слов / терминов в столбце ТЕКСТ
  2. Количество строк / документов, соответствующих критериям
  3. Длина слов / терминов

Например, этот SQL может быть запущен для извлечения всех строк, соответствующих данному слову XYZ:

SELECT * 
FROM   my_table 
WHERE  MATCH (my_text_column) against ('XYZ' IN boolean mode) ;

Предостережение: если вы добавите ORDER BY к этому запросу, время выполнения будет зависеть от нескольких параметров, один из которых - количество совпадающих строк / документов. Так что будьте осторожны.

Однако, как не имеет ничего этого. Он вынужден линейно сканировать предложение / строку и найти все совпадающие термины. Добавление джокера добавляет беспорядка. Как вы можете себе представить, он отлично работает с небольшими строками, но для более длинных предложений потерпит неудачу. И определенно не сравнимо, когда есть параграф или целая страница текста и т. Д.

FTS более эффективен, мощен (особенно для средств разбиения по словам и базовых функций) ... но проверьте ваши требования, потому что иногда БД не поддерживают все языки, например, MSSQL не поддерживает греческий (проверьте на этой странице http://msdn.microsoft.com/en-us/library/ms176076%28v=sql.110%29.aspx)

Другие вопросы по тегам