我试图调试在许多tabls(10-11)加入了一个相当复杂的存储过程。 我看到,对于树行的估计数量从实际的行数drasticly不同的部分 - 在最坏的情况SQL服务器的估计,1排将被退回,但实际上返回55000行的时候!
我试图找出为什么这是 - 我所有的统计数据均达到最新的,我已经在几个表更新与FULLSCAN统计。 我不使用任何用户定义的函数或表变量。 至于我可以看到SQL服务器应该能够准确估计很多行会怎样退还,但它仍然选择它来执行的RDI查找成千上万的(这情况下,计划当它被期望仅执行1或2)。
我能做些什么,试图理解为什么行的估计数目超出由这么多呢?
更新:所以在看这个计划我发现一个特别的节点,这似乎suspicous -其表扫描上使用以下predecate表:
status <> 5
AND [type] = 1
OR [type] = 2
该谓词返回整个表(630行 - 表扫描本身何尝不是表现不佳的来源),但SQL服务器的行仅为37 SQL服务器的估计数量然后继续做这几个嵌套循环到RDI查找,索引扫描和索引查找。 难道这是我的巨大的失算之源? 我如何得到它估计行更明智的号码?
SQL Server
将每个指数为最多200
个范围如下数据(来自这里 ):
通常情况下,人口最多的价值观进入RANGE_HI_KEY
。
然而,他们可以进入的范围,这可能导致在分布的偏斜。
想象一下,这些数据(其中包括其他):
行的关键值计数
1 1
2 1
3 10000
4 1
SQL Server
通常建立两个范围: 1
至3
和4
至下一个填充的值,这使得这些统计:
RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS
3 2 10000 1 2
,,比如说,在搜索时,这意味着2
,即只有1
行,最好是使用索引访问。
但是,如果3
而来的范围之内,统计是这些:
RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS
4 10002 1 3334 3
优化器认为有3334
行的关键2
和索引访问是太贵了。
它使用的统计数据,它保持每个索引。
(您也可以创建非索引列的统计信息)
要更新数据库中的每个表中所有的统计数据( 警告 :将在非常大的数据库一段时间,不要没有你的DBA检查做生产服务器上...。):
exec sp_msforeachtable 'UPDATE STATISTICS ?'
如果你没有定期计划的作业重建最活跃的指标(即手插入或删除的),你应该考虑重建索引时(相同的警告与上述适用):
exec sp_msforeachtable "DBCC DBREINDEX('?')"
- 通过查询优化器在Microsoft SQL Server 2008中使用的统计信息
既然你已经更新了统计,我想尝试,以消除任何参数嗅探:
CREATE PROCEDURE xyz
(
@param1 int
,@param2 varchar(10)
)AS
DECLARE @param_1 int
,@param_2 varchar(10)
SELECT @param_1=@param1
,@param_2=@param2
...complex query here....
...WHERE column1=@param_1 AND column2=@param_2....
go