假设我有一个包含200000条记录的Person表,它的GUID主键上有一个聚簇索引。此GUID是使用SQL Server(2008 R2)提供的NEWSEQUENTIALID()构造生成的。此外,LastName(varchar(256))列上有一个常规索引。
对于每条记录,我都生成了一个唯一的名称(Lastname_1到Lastname_200000),现在我正在玩一些查询,并且发现我的标准越严格,SQL Server就会越慢返回实际结果。而这种表现意义非常严重。
例如:
SELECT * FROM Person WHERE Lastname LIKE '%Lastname_123456%'
慢于
SELECT * FROM Person WHERE Lastname LIKE '%Lastname_123%'
通过设置统计数据来衡量响应时间:
SET STATISTICS TIME ON
我可以想象这是由此造成的
1)由于LIKE子句本身,因为它以%开头,所以不能在该特定列上使用inde,
2)SQL必须更多地考虑我的“更大问题”。
这有什么道理吗?有没有办法避免这种情况?
编辑: 要为此问题添加一些上下文,这是“免费搜索”的用例的一部分。当用户输入完整的姓氏时,我非常希望系统快速。
我应该如何使这些案件表现出色?我应该避免使用'%xxx%'构造并像施工一样去'xxx%'吗?这确实增加了很多速度,但代价是用户的一些灵活性......
答案 0 :(得分:1)
你正好使用数字2,因为第二个LIKE必须匹配字符串中的更多字符,SQL在找到不匹配的字符时停止搜索,因此搜索较小的搜索字符串需要较少的字符串匹配迭代 - 即使你得到更多的结果。
对于#1 - 如果可能的话,SQL将使用索引,但可能会进行索引扫描(可能是聚簇索引),因为使用通配符无法进行搜索。它还取决于索引中包含的内容 - 因为您选择了所有列,所以可能会发生表扫描,因为您可以使用的索引不会覆盖您的查询(除非它使用聚簇索引)
检查执行计划 - 您可能会看到表扫描
答案 1 :(得分:0)
通常,SQL Server不使用LIKE上的索引。
This文章可以帮助指导您