23

我的问题是关于使用全文。据我所知,以 % 开头的查询从不使用索引:

SELECT * from customer where name like %username%

如果我对此查询使用全文,我可以取得更好的性能吗?SQL Server 能否将全文索引优势用于 %username% 之类的查询?

4

6 回答 6

44

简短的回答

在 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,可以通过创建新列、将其值设置为与目标列相反的值并对其进行索引来执行有效的后缀搜索。然后可以查询如下:

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%';

它实现了(可能)索引的中缀搜索,但它并不是特别漂亮(而且我从未测试过这个查询优化器是否会在其计划中使用这两个索引)。

于 2010-12-01T06:34:15.563 回答
3

您必须了解索引是如何工作的。索引与百科全书的枯木版完全相同。

如果您使用:

SELECT * from customer where name like username%

全文或没有全文的索引应该可以工作。但

SELECT * from customer where name like %username%

永远不会使用索引。这将是一个耗时的查询。

于 2010-11-16T13:44:19.297 回答
0

在我对全文索引的了解中,我将做出以下推断:

  1. 在建立索引时,它解析文本,搜索单词(一些 RDBMS,如 MySQL,只考虑长度超过 3 个字符的单词),并将单词放入索引中。
  2. 当您在全文索引中搜索时,您会搜索单词,然后链接到该行。
  3. 如果我对前两个(对于 MSSQL)是正确的,那么它只有在您搜索 WORDS 时才有效,长度为 4 个或更多字符。如果您寻找“椅子”,它不会找到“扶手椅”。

假设所有这些都是正确的,我将继续进行以下声明:全文索引实际上是一个索引,它使搜索更快。它很大,搜索的可能性比 LIKE 少,但速度更快。

更多信息: http:
//www.developer.com/db/article.php/3446891
http://en.wikipedia.org/wiki/Full_text_search

于 2010-11-16T13:20:05.383 回答
0

Like 和 contains 是非常不同的——

取以下数据值

“约翰·史密斯”“山姆·史密斯”“约翰·富勒”

像“%”“山姆·史密斯”

像 '%s%' 'john smith' 'sam smith'

包含's'

包含“约翰”“约翰史密斯”“约翰富勒”

包含 's*' 'john smith' 'sam smith'

contains s返回与 contains s* 相同 - 忽略初始星号,这有点痛苦,但索引是单词 - 不是字符

于 2016-05-05T15:34:58.310 回答
-1

您可以使用:

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

或者

SELECT * from customer where FREETEXT(name, 'username')
于 2019-06-22T06:50:24.667 回答
-3

https://stackoverflow.com/users/289319/mike-chamberlain,您说得对,因为您认为仅搜索“链”是不够的,其中 Name LIKE ' chain %' AND Name_Reversed LIKE 'niahc%'不等于'%chain%'****

于 2017-05-19T13:01:50.123 回答