当前位置:  开发笔记 > 编程语言 > 正文

SQL Server查询执行计划在使用的索引上显示错误的"实际行数",并且性能非常慢

如何解决《SQLServer查询执行计划在使用的索引上显示错误的"实际行数",并且性能非常慢》经验,为你挑选了1个好方法。

今天我在兼容级别为80(SQL2000)的数据库中运行在Sql Server 2005 SP2上运行的存储过程时偶然发现了一个有趣的性能问题.

proc运行大约8分钟,执行计划显示索引的使用情况,实际行数为1.339.241.423,比表本身的"实际"实际行数(1.144.640)高出约1000倍,如正确显示估计行数.因此查询计划优化器给出的实际行数绝对是错误的!

替代文字

有趣的是,当我将proc中的procs参数值复制到局部变量而不是在实际查询中使用局部变量时,一切正常 - proc运行18秒,执行计划显示正确的实际行数.

编辑:正如TrickyNixon所建议的那样,这似乎是参数嗅探问题的一个标志.但事实上,我在两种情况下都完全相同的执行计划.相同的指数以相同的顺序使用.我看到的唯一区别是直接使用参数值时PK_ED_Transitions索引上的实际行数高的方法.

我已经完成了dbcc dbreindex和UPDATE STATISTICS,但没有任何成功.dbcc show_statistics也显示索引的良好数据.

proc是使用RECOMPILE创建的,因此每次运行时都会编译新的执行计划.

更具体一点 - 这个速度很快:

CREATE  Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE 
as

set nocount on

declare @local datetime
set @local = @Param

select 
some columns
from 
table1
where
column = @local
group by
some other columns

而且这个版本的运行速度非常慢,但产生完全相同的执行计划(除了使用索引的实际行数太高):

CREATE  Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE 
as

set nocount on

select 
some columns
from 
table1
where
column = @Param
group by
some other columns

有任何想法吗?谁知道Sql Server在计算查询计划时从哪里获取实际行计数值?

更新:我在另一台服务器上尝试了查询,并将copat模式设置为90(Sql2005).它的行为相同.我想我会打开ms支持电话,因为这对我来说就像一个bug.



1> Jan..:

好的,最后我自己做到了.

这两个查询计划在一个小细节上是不同的,我最初错过了.慢速使用嵌套循环运算符将两个子查询连接在一起.和的结果在当前行高数计数上的索引扫描运算符,其是简单地multiplicating输入的行数与输入B的行数的结果.

我仍然不知道为什么优化器决定使用嵌套的循环,而不是它运行1000计时器在这种情况下,更快的哈希匹配的,但我可以通过创建一个新的索引处理我的问题,从而使发动机不索引查找斯塔特而不是嵌套循环下的索引扫描.

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有