Полнотекстовый поиск против LIKE - PullRequest
19 голосов
/ 16 ноября 2010

Мой вопрос об использовании полного текста. Как я знаю, запросы, начинающиеся с%, никогда не используют индекс:

SELECT * from customer where name like %username%

Если я использую полный текст для этого запроса, могу ли я повысить производительность? Может ли SQL Server использовать преимущества полнотекстового индекса для запросов, таких как% username%?

Ответы [ 6 ]

35 голосов
/ 01 декабря 2010

Короткий ответ

Не существует эффективного способа выполнить поиск в инфиксах в SQL Server, ни с использованием LIKE в индексированном столбце, ни с полнотекстовым индексом.

Длинный ответ

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

Полный текст SQL Server поддерживает подмножество LIKE с префиксным оператором термина.Из документов (http://msdn.microsoft.com/en-us/library/ms187787.aspx):

SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');

будут возвращаться продукты с именами цепная пила, цепная почта и т. Д. Функционально это ничего не даст вам по сравнению со стандартным оператором LIKE (LIKE 'Chain%') и, какПока столбец индексируется, использование LIKE для поиска с префиксом должно обеспечивать приемлемую производительность.

Оператор LIKE позволяет помещать подстановочный знак в любом месте, например LIKE '%chain', и, как вы упомянули, это не позволяет индексуиспользуется, но с полным текстом звездочка может появиться только в конце термина запроса, так что это вам не поможет.

Используя LIKE, является возможным для эффективного выполнения. postfix выполняет поиск путем создания нового столбца, установки его значения в обратном направлении к целевому столбцу и его индексации. Затем можно выполнить запрос следующим образом:

SELECT Name
FROM Production.Product
WHERE Name_Reversed LIKE 'niahc%'; /* "chain" backwards */

, который возвращает товары с их названиямизаканчивая "chain".

Полагаю, вы могли бы затем объединить префикс и обратный постфиксный хак:

SELECT Name
FROM Production.Product
WHERE Name LIKE 'chain%'
AND Name_Reversed LIKE 'niahc%';

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

3 голосов
/ 16 ноября 2010

Вы должны понимать, как работает индекс. Указатель - это то же самое, что и энциклопедическое издание "Мертвое дерево".

Если вы используете:

SELECT * from customer where name like username%

Индекс в полнотекстовом или без полнотекстового должен работать. но

SELECT * from customer where name like %username%

никогда не будет работать с индексом. и это будет трудоемкий запрос.

0 голосов
/ 22 июня 2019

Вы можете использовать:

SELECT * from customer where CONTAINS(name, 'username')

ИЛИ

SELECT * from customer where FREETEXT(name, 'username')
0 голосов
/ 19 мая 2017

https://stackoverflow.com/users/289319/mike-chamberlain, вы совершенно правы, поскольку вы предлагаете, что недостаточно что-то искать ' chain ' WHERE Name LIKE 'chain%' AND Name_Reversed LIKE 'niahc%' не эквивалентно подобно '% chain%' ****

0 голосов
/ 05 мая 2016

Вроде и содержит очень разные -

Примите следующие значения данных

Джон Смит 'Сэм Смит' 'Джон Фуллер'

как 's%' "Сэм Смит"

как "% s%" 'Джон Смит' "Сэм Смит"

содержит 's'

содержит «Джон» 'Джон Смит' 'Джон Фуллер'

содержит 's *' 'Джон Смит' 'Сэм Смит'

содержит s возвращает то же самое, что и содержит s * - начальная звездочка игнорируется, что немного неприятно, но тогда индекс состоит из слов, а не символов

0 голосов
/ 16 ноября 2010

Из того, что я знаю о полнотекстовых индексах, я сделаю следующие экстраполяции:

  1. После индексации он анализирует текст, ищет слова (некоторые РСУБД, например, MySQL, рассматривают слова длиннее 3 символов) и помещает слова в индекс.
  2. При поиске в полнотекстовом индексе вы ищете слова, которые затем ссылаются на строку.
  3. Если я прав насчет первых двух (для MSSQL), то это будет работать только в том случае, если вы будете искать СЛОВА длиной 4 или более символов. «Кресло» не найдется, если вы ищете «кресло».

Предполагая, что все правильно, я продолжу и сделаю следующее утверждение: полнотекстовый индекс фактически является индексом, который ускоряет поиск. Он большой и имеет меньше возможностей поиска, чем LIKE, но это намного быстрее.

Дополнительная информация:
http://www.developer.com/db/article.php/3446891
http://en.wikipedia.org/wiki/Full_text_search

...