在SQL Server上喜欢vs包含


Answers:


174

第二个(假设您的意思是CONTAINS,实际上将其放入有效查询中)应该更快,因为它可以使用某种形式的索引(在这种情况下为全文索引)。当然,这种形式的查询只能列在全文索引中时。如果不是,则仅第一种形式可用。

使用LIKE的第一个查询将无法使用索引,因为它以通配符开头,因此始终需要全表扫描。


CONTAINS查询应该是:

SELECT * FROM table WHERE CONTAINS(Column, 'test');

@edze-您的意思是,已经链接到我第一次提到的同一页面CONTAINS?怎么了 该问题的原始形式Column CONTAIN("%test%",Column)>0几乎没有哪个是有效的。还是不完全正确。
Damien_The_Unbeliever

这有助于我们对SharePoint进行查询。拥有另一个“好答案”徽章。
ouflak

14

在SQL Server 2012实例上运行了两个查询之后,我可以确认第一个查询对我而言是最快的。

使用LIKE关键字的查询显示了聚集索引扫描。

CONTAINS还与另外的运营商聚集索引扫描全文的匹配和合并联接。

计划


8
聚簇索引叶页。一个LIKE与一家领先的通配符查询将无法有效地使用索引部分。它只需要扫描整个内容即可。毫无疑问,在某些情况下,完整CI扫描的性能要优于使用全文索引的查询(例如,如果有很高比例的行匹配),这在很大程度上是一个例外,不是您可以确认的一些通用规则”。
马丁·史密斯

好吧,我正在寻找一个实际的执行计划,该计划可以获取200,000条记录。将两个查询放入批处理中,都扫描了聚集索引,但是除此之外,“ CONTAINS”查询的确增加了FULL TEXT MATCH和MERGE JOIN的开销。
MI C

如果选择合并联接,则SQL Server估计超过x%的行最终将与谓词匹配。(其中X = 临界点)。在那种情况下,我想两者最终可能会相当平均地匹配。执行计划中显示的成本只是估算(甚至在实际计划中)。尽管FT计划中还有其他执行计划运营商,但确实有一些好处。如果合并联接用完了FT结果,并且可以不必对进行评估,则可以在扫描结束前停止它LIKE
马丁·史密斯

1
我已经运行了一个类似的查询来检查sql 2012中的执行计划,它给了我一个Index Seek。也许在此示例中,表格几乎是空的。在某些情况下,sql使用非常小的表中的索引扫描来代替索引,因为它速度更快。
胡安

8

我认为这CONTAINS花了更长的时间并使用了,Merge因为查询中有破折号(“-”)adventure-works.com

破折号是一个断字,因此CONTAINS搜索全文索引,adventure然后搜索works.com并合并结果。


8

也可以尝试从此更改:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

对此:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

前者将查找具有“ 这是一个测试 ”和“ 一个测试用例是计划 ”之类值的记录 ”之类的值的记录。

后者还将找到诸如“ 我正在测试 ”和“ 这是最大的 ” 等值的记录。


4
在搜寻字词前后加上星号是否有效?在阅读的文档时CONTAINS,它仅提及使用诸如“ test *”之类的前缀术语,而不使用诸如“ test”之类的后缀术语以及诸如“ * test ”之类的完整子串搜索。我还没有尝试过。
马特·福赛斯(Matt forsythe)

5
如果您阅读了CONTAINS的文档(docs.microsoft.com/zh-cn/sql/t-sql/queries/…),则仅支持搜索前缀。我已经尝试了无数次,并且无法通过Contains(Column,'“ test ”')找到“这是最大的”(在SQL Server中)
cl0rkster
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.