【发布时间】:2010-11-24 11:29:14
【问题描述】:
我在 SQL Server 2005 中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在执行聚集索引扫描,这花费了 84%。我读到我必须修改一些东西才能在那里获得聚集索引搜索,但我不知道要修改什么。
我将不胜感激。
谢谢,
布赖恩
【问题讨论】:
-
查询和表架构怎么样?
标签: sql-server-2005 clustered-index
我在 SQL Server 2005 中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在执行聚集索引扫描,这花费了 84%。我读到我必须修改一些东西才能在那里获得聚集索引搜索,但我不知道要修改什么。
我将不胜感激。
谢谢,
布赖恩
【问题讨论】:
标签: sql-server-2005 clustered-index
没有任何细节很难猜出问题是什么,甚至根本就没有问题。选择扫描而不是搜索可能受多种因素影响:
SELECT * FROM <table>。这是一个微不足道的情况,可以通过聚集索引扫描完美覆盖,无需考虑其他任何事情。WHERE column = @value,但列是VARCHAR(Ascii),@value 是NVARCHAR(Unicode)。(foo, bar) 上,但 WHERE 子句仅位于 bar 上。 这些是为什么在预期聚集索引搜索时可能会出现聚集索引扫描的一些快速指示。这个问题非常笼统,除了依靠 8 号球外,不可能给出“为什么”的答案。现在,如果我将您的问题正确记录并正确表达,那么期望聚集索引 seek 这意味着您正在搜索基于聚集键值的唯一记录。在这种情况下,问题必须与 WHERE 子句的 SARGability 相关。
【讨论】:
Special = true (1),那么简单查询Select * From table where Special = 0会一直选择一个表扫描。即使在特殊列上存在索引也是如此,只要该索引不是聚集索引。 (如果索引是聚集索引,那么优化器当然会选择范围查找。)
如果查询包含表中超过一定百分比的行,优化器将选择进行扫描而不是查找,因为它预测在这种情况下它将需要更少的磁盘 IO(对于查找,它返回的每一行在索引中的每个级别都需要一个磁盘 IO),而对于扫描,整个表中的每行只有一个磁盘 IO。
因此,如果在 b-tree 索引中有 5 个级别,那么如果查询将生成表中超过 20% 的行,则读取整个表比为每个执行 5 个 IO 更便宜20% 的行...
您能否进一步缩小查询的输出范围,以减少流程中此步骤返回的行数?这将有助于它选择搜索而不是扫描。
【讨论】: