我应该怎样做才能获得聚集索引查找而不是聚集索引扫描?
我在 SQL Server 2005 中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在执行聚集索引扫描,这花费了 84% 的成本。我读到我必须修改一些东西才能在那里进行聚集索引搜索,但我不知道要修改什么。
我将不胜感激任何帮助。
谢谢,
布莱恩
I've got a Stored Procedure in SQL Server 2005 and when I run it and I look at its Execution Plan I notice it's doing a Clustered Index Scan, and this is costing it the 84%. I've read that I've got to modify some things to get a Clustered Index Seek there, but I don't know what to modify.
I'll appreciate any help with this.
Thanks,
Brian
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有任何细节,很难猜测问题是什么,甚至根本无法猜测是否是问题。选择扫描而不是查找可能由许多因素驱动:
SELECT * FROM 。这是一个简单的情况,可以通过聚集索引扫描完美地覆盖,无需考虑其他任何事情。
WHERE column = @value
,但列为VARCHAR
(Ascii),@value 为NVARCHAR
(Unicode)。(foo, bar)
上,但 WHERE 子句仅位于bar
上。这些是一些快速提示,说明为什么在预期聚集索引查找时可能会出现聚集索引扫描。这个问题非常笼统,除了依靠 8 号球之外不可能给出“为什么”的答案。现在,如果我认为您的问题被正确记录并正确表达,那么期望聚集索引seek意味着您正在基于聚集键值搜索唯一记录。在这种情况下,问题必须出在 WHERE 子句的 SARGability 上。
W/o any detail is hard to guess what the problem is, and even whether is a problem at all. The choice of a scan instead of a seek could be driven by many factors:
SELECT * FROM <table>
. This is a trivial case that would be perfectly covered by a clustred index scan with no need to consider anything else.WHERE column = @value
but column isVARCHAR
(Ascii) and @value isNVARCHAR
(Unicode).(foo, bar)
but the WHERE clause is onbar
alone.These are some quick pointers why a clustered index scan may be present when a clustered index seek is expected. The question is extremly generic and is impossible to give an answer 'why', other than relying on an 8 ball. Now if I take your question to be properly documented and correctly articulated, then to expect a clustered index seek it means you are searching an unique record based on a clustred key value. In this case the problem has to be with the SARGability of the WHERE clause.
如果查询包含表中超过一定比例的行,优化器将选择执行扫描而不是查找,因为它预测在这种情况下需要更少的磁盘 IO(对于查找,它需要一个它返回的每一行的索引中每个级别的磁盘 IO),而对于扫描,整个表中的每行只有一个磁盘 IO。
因此,如果 b 树索引中有 5 个级别,那么如果查询将生成表中超过 20% 的行,则读取整个表比为这 20% 中的每一个进行 5 次 IO 更便宜rows...
您能否进一步缩小查询的输出范围,以减少过程中此步骤返回的行数?这将有助于它选择搜索而不是扫描。
If the Query incldues more than a certain percentage of the rows in the table, the optimizer will elect to do a scan instead of a seek, because it predicts that it will require fewer disk IOs in that case (For a Seek, It needs one Disk IO per level in the index for each row it returns), whereas for a scan there is only one disk IO per row in the entire table.
So if there are, say 5 levels in the b-tree Index, then if the query will generate more than 20% of the rows in the table, it is cheaper to read the whole table than make 5 IOs for each of the 20% rows...
Can you narrow the output of the query a bit more, to reduce the number of rows returned by this step in the process? That would help it choose the seek over the scan.