9

我在 SQL Server 2005 中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在执行聚集索引扫描,这花费了 84%。我读过我必须修改一些东西才能在那里获得聚集索引搜索,但我不知道要修改什么。

我会很感激这方面的任何帮助。

谢谢,

布赖恩

4

2 回答 2

20

没有任何细节很难猜出问题是什么,甚至根本就没有问题。选择扫描而不是搜索可能由许多因素驱动:

  • 该查询表示一个覆盖整个表的结果集。IE。查询很简单SELECT * FROM <table>。这是一个微不足道的情况,可以通过聚集索引扫描完全覆盖,无需考虑其他任何事情。
  • 优化器别无选择:
    • 该查询表示整个表的子集,但过滤谓词位于不属于聚集键的列上,并且这些列上也没有非聚集索引。除了全面扫描之外,这些不是替代计划。
    • 该查询对聚集索引键中的列具有过滤谓词,但它们不是SARGable。过滤谓词通常需要重写以使其成为 SARGable,正确的重写取决于具体情况。由于隐式转换规则,可能会出现更微妙的问题,例如。过滤谓词是WHERE column = @value,但列是VARCHAR(Ascii),@value 是NVARCHAR(Unicode)。
    • 该查询在聚集键中的列上有 SARGale 过滤谓词,但最左边的列没有被过滤。IE。聚集索引在列上,(foo, bar)但 WHERE 子句是bar单独的。
  • 优化器选择扫描。
    • 当替代方案是非聚集索引然后扫描(或范围搜索)但选择使用聚集索引时,通常可以将原因追踪到索引临界点,因为查询的非聚集索引覆盖范围不足投影。请注意,这不是您的问题,因为您期望聚集索引查找,而不是非聚集索引查找(假设问题是 100% 准确并记录在案......)
    • 基数估计。查询成本估计基于聚集索引键统计信息,该统计信息提供对结果基数的估计(即匹配多少行)。在一个简单的查询中这不会发生,因为任何对搜索或范围搜索的估计都将低于扫描的估计,无论统计信息如何,但在复杂查询中,在多个表上具有连接和过滤器,事情更复杂,并且计划可能包括预期搜索的扫描,因为查询优化器可能会选择连接评估顺序与观察者期望相反的计划。逆序选择可能是正确的(大多数时候),也可能是有问题的(通常是由于统计数据已过时或参数嗅探)。
    • 订购保证。扫描将以保证的顺序生成结果,执行树上较高的元素可能会受益于此顺序(例如,可以消除排序或假脱机,或者可以使用合并连接来代替散列/嵌套连接)。总体而言,由于选择了明显较慢的访问路径,查询成本会更好。

这些是为什么在预期聚集索引查找时可能会出现聚集索引扫描的一些快速指示。这个问题非常笼统,除了依靠 8 号球外,不可能给出“为什么”的答案。现在,如果我将您的问题正确记录并正确表达,那么期望聚集索引搜索意味着您正在搜索基于聚集键值的唯一记录。在这种情况下,问题必须与 WHERE 子句的 SARGability 相关。

于 2009-08-31T22:59:54.247 回答
7

如果查询包含表中超过一定百分比的行,优化器将选择进行扫描而不是查找,因为它预测在这种情况下它将需要更少的磁盘 IO(对于查找,它需要一个它返回的每一行的索引中的每个级别的磁盘 IO),而对于扫描,整个表中的每行只有一个磁盘 IO。

因此,如果 b-tree 索引中有 5 个级别,那么如果查询将生成表中超过 20% 的行,则读取整个表比为 20% 中的每一个进行 5 次 IO 更便宜行...

您能否进一步缩小查询的输出范围,以减少流程中此步骤返回的行数?这将有助于它选择搜索而不是扫描。

于 2009-08-31T21:49:33.437 回答