我该怎么做才能获得聚集索引而不是聚集索引扫描?

Bri*_*tul 9 sql-server-2005 clustered-index

我在SQL Server 2005中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在进行聚簇索引扫描,这使得它的成本为84%.我已经读过,我必须修改一些东西以获得Clustered Index Seek,但我不知道要修改什么.

我会感激任何帮助.

谢谢,

布赖恩

Rem*_*anu 20

没有任何细节很难猜出问题是什么,甚至是否是一个问题.扫描而不是搜索的选择可能受到许多因素的驱动:

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

这些是一些快速指针,指出在预期聚簇索引搜索时可能存在聚簇索引扫描的原因.这个问题非常通用,除了依靠8球之外,不可能回答'为什么'.现在,如果我将您的问题正确记录并正确表达,那么期望聚集索引寻找它意味着您正在根据已确定的键值搜索唯一记录.在这种情况下,问题必须与WHERE子句的SARGability有关.


Cha*_*ana 6

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

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

您是否可以将查询的输出缩小一点,以减少此过程中此步骤返回的行数?这将有助于它选择扫描的搜索.