Полнотекстовый поиск vs LIKE
Мой вопрос об использовании fulltext.As я знаю, как запросы, которые начинаются с% никогда не используйте индекс:
SELECT * from customer where name like %username%
Если я использую fulltext для этого запроса, можно ли повысить производительность? Может ли SQL Server использовать преимущества полнотекстового индекса для запросов, таких как% username%?
Ответы
Ответ 1
Короткий ответ
Нет эффективного способа выполнения инфиксных поисков в SQL Server, не используя LIKE
в индексированном столбце или с полным текстом.
Длинный ответ
В общем случае нет полнотекстового эквивалента оператору LIKE. В то время как LIKE работает над строкой символов и может выполнять произвольные совпадения подстановок против чего-либо внутри цели, по дизайну fulltext работает только на целые слова/термины. (Это небольшое упрощение, но это будет сделано для целей этого ответа.)
Полнотекстовый SQL Server поддерживает подмножество LIKE с оператором оператора префикса. Из документов (http://msdn.microsoft.com/en-us/library/ms187787.aspx):
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');
будет возвращать продукты с именем chainaw, chainmail и т.д. Функционально это не дает вам ничего по сравнению с стандартным оператором LIKE
(LIKE 'Chain%'
), и пока индексируется столбец, используя LIKE для префиксного поиска должны обеспечивать приемлемую производительность.
Оператор LIKE позволяет помещать подстановочный шаблон в любом месте, например LIKE '%chain'
, и, как вы упомянули, это предотвращает использование индекса. Но с полным текстом звездочка может появляться только в конце запроса, поэтому вам это не поможет.
Используя LIKE, можно выполнить эффективные постфиксные поиски, создав новый столбец, установив его значение на обратный целевой столбец и проиндексируя его. Затем вы можете запросить следующее:
SELECT Name
FROM Production.Product
WHERE Name_Reversed LIKE 'niahc%'; /* "chain" backwards */
который возвращает продукты с именами, заканчивающимися "цепочкой".
Я предполагаю, что вы могли бы затем комбинировать префикс и отменить postfix hack:
SELECT Name
FROM Production.Product
WHERE Name LIKE 'chain%'
AND Name_Reversed LIKE 'niahc%';
который реализует (потенциально) индексированный инфиксный поиск, но он не особенно хорош (и я никогда не тестировал это, чтобы увидеть, будет ли оптимизатор запросов даже использовать оба индекса в своем плане).
Ответ 2
Вам нужно понять, как работает индекс. Индекс - это то же самое, что и издательская энциклопедия мертвого дерева.
Если вы используете:
SELECT * from customer where name like username%
В полнотекстовом или полном тексте должен работать индекс. но
SELECT * from customer where name like %username%
никогда не будет работать с индексом. и это будет трудоемкий запрос.
Ответ 3
Из того, что я знаю о полнотекстовых индексах, я сделаю следующие экстраполяции:
- При индексировании он анализирует текст, ищет слова (некоторые РСУБД, такие как MySQL, учитывают только слова длиной более 3 символов) и помещают слова в индекс.
- При поиске в полнотекстовом индексе вы ищете слова, которые затем ссылаются на строку.
- Если я прав о первых двух (для MSSQL), он будет работать, только если вы ищете СЛОВА с длиной 4 или более символов. Он не найдет "кресло", если вы ищете "стул".
Предполагая, что все правильно, я продолжу и сделаю следующее утверждение. Полнотекстовый индекс на самом деле является индексом, который ускоряет поиск. Он большой и имеет меньше возможностей поиска, чем LIKE, но он быстрее.
Дополнительная информация:
http://www.developer.com/db/article.php/3446891
http://en.wikipedia.org/wiki/Full_text_search
Ответ 4
Вроде и содержит очень разные -
Возьмите следующие значения данных
'john smith'
'Сэм Смит'
'john fuller'
like 's%'
'sam smith'
like '% s%'
'Джон Смит'
'sam smith'
содержит 's'
содержит 'john'
'Джон Смит'
'john fuller'
содержит 's *'
'Джон Смит'
'sam smith'
содержит s возвращает то же самое, что и s * - исходная звездочка игнорируется, что немного больно, но тогда индекс имеет слова - не символы
Ответ 5
Ты можешь использовать:
SELECT * from customer where CONTAINS(name, 'username')
ИЛИ ЖЕ
SELECT * from customer where FREETEXT(name, 'username')
Ответ 6
https://stackoverflow.com/users/289319/mike-chamberlain, вы совершенно правы, поскольку вы предполагаете, что этого недостаточно, чтобы найти что-то "цепочку" WHERE Name LIKE 'chain%'
AND Name_Reversed LIKE 'niahc%' не эквивалентен как '% chain%' ****