【问题标题】:Avoid index scan in SQL Server 2008 R2避免 SQL Server 2008 R2 中的索引扫描
【发布时间】:2017-09-07 21:46:12
【问题描述】:

我需要一些帮助。

我目前正在对一些需要一段时间才能返回结果的动态 SQL 进行故障排除。我正在使用 SQL Server 2008 R2,构建 10.50.4305

我已经执行了 SQL 跟踪,所以我现在可以看到发生了什么,基本上罪魁祸首是聚集索引扫描。

选择包含:

WHERE 
    Name LIKE @Query + '%' ESCAPE '\' 
ORDER BY

这会导致聚集索引扫描。

如果我将选择更改为

WHERE 
    Name LIKE 'value' + '%' ESCAPE '\' 
ORDER BY

我得到一个索引查找和一个键查找。

我看起来使用了 forceseek 查询提示,但我得到了错误....

消息 8622,第 16 级,状态 1,第 6 行
由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示和不使用 SET FORCEPLAN 的情况下重新提交查询。

任何关于如何在查询中保留参数并避免聚集索引扫描的帮助或建议将不胜感激。

更新(取自 Shnugo 的评论)

我已将查询添加到原始问题中,无论结果是快还是慢,@Query 的值每次都是相同的

DECLARE @Query nvarchar(50)

SET @Query = 'EIKO'

SET NOCOUNT ON
SELECT TOP 5 pex.Ric.Name AS Id, pex.Ric.Name + '|' + pex.Ric.DisplayName AS Name FROM pex.Ric WITH (nolock) WHERE pex.Ric.Name LIKE @Query + '%' ESCAPE '\' ORDER BY PeId, Name

【问题讨论】:

  • 您能否发布表结构、表上定义的任何索引以及您的完整查询?
  • 如果你的名字列有索引,我在这两种情况下都找到了,请提供测试数据供我们检查问题
  • A LIKE 最后带有 % 的搜索应该能够使用索引...您是否尝试将变量 @Query 设置为相同的值,这可以快速运行, (如果放置为文字)?如果您的@Query 包含其他字符,例如下划线或[] 括号(更多),这些字符在LIKE 模式中使用,这可能会欺骗您...提供@Query 内容的一些示例跨度>
  • 补充:您谈到dynamic SQL... 在SQL 中,您经常会在对象名称中找到下划线(例如object_id)或像[dbo],[SomeTable] 这样的括号。 LIKE 将尝试将这些用作模式...
  • 如果该语句确实是动态 SQL,难道不应该更好地编写只查询您想要过滤的内容,而不是在执行中计算和连接吗?

标签: sql-server tsql sql-server-2008-r2 clustered-index


【解决方案1】:

正如我在 cmets 中指出的那样,我假设动态 SQL 中的某些字符被解释为模式。 ESCAPE 的使用可能是一个提示,您知道这一点并插入替换字符以将这些特殊字符标记为正常...

看起来,好像你只是在寻找相同的开始......试试这个

WHERE LEFT(Name,LEN(@Query))=@Query

这应该从Name 的左侧减少相同数量的字符,并将其与您的@Query 变量进行比较。

这种方法不会那么快,因为它不是 sargable 并且也不能使用索引,但是 - 如果我的假设是正确的 - 它应该比 LIKE 更快,它正在做复杂的事情每行的模式检查...

更新(取自下面的 cmets)

会不会是其他重操作窃取了服务器的资源?你试过没有ORDER BY吗?

我刚刚试了一下,我可以重现这个。搜索字面意思是让优化器提前知道一切:最佳预测、统计数据和索引的最佳使用。此外,您的结果可能具有误导性。如果您一遍又一遍地执行此操作,结果将被缓存。使用相同的查询,您可能会很快得到答案 - 但它们来自缓存...

参数嗅探也可能是个问题。

将语句创建为字符串(使用文字)并使用EXEC 运行可能会有所帮助。

【讨论】:

  • 感谢您的回复。这个比较陌生。有时查询会在 2 或 3 秒内返回,有时会在几分钟内返回。每次执行计划都是一样的,无论结果是快还是慢。每次都是聚集索引扫描。我怎样才能理解发生了什么?
  • @user2841861 请提供更多详细信息,尤其是@Query 的内容,以便快速和慢速运行。
  • 我已将查询添加到原始问题中,无论结果是快还是慢,@Query 的值每次都是相同的。
  • @user2841861, 会不会是其他重操作窃取了服务器的资源?你试过没有ORDER BY吗?
  • 删除订单意味着查询每次运行都很快。仍然有一个聚集索引扫描,但执行计划只有 4 个项目,而不是 6 个项目的 order by
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多