Что такое полнотекстовый поиск против 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). Запрос не будет зависеть от
- Количество слов / терминов в столбце ТЕКСТ
- Количество строк / документов, соответствующих критериям
- Длина слов / терминов
Например, этот 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)