SQL Server如何制定出估计的行数?(How does SQL server work out

2019-07-19 14:26发布

我试图调试在许多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查找,索引扫描和索引查找。 难道这是我的巨大的失算之源? 我如何得到它估计行更明智的号码?

Answer 1:

SQL Server将每个指数为最多200个范围如下数据(来自这里 ):

  • RANGE_HI_KEY

    示出的直方图步骤的上边界的密钥值。

  • RANGE_ROWS

    指定有多少行范围内(他们比这个小RANGE_HI_KEY比以前小,但更大RANGE_HI_KEY )。

  • EQ_ROWS

    指定有多少行正好等于RANGE_HI_KEY

  • AVG_RANGE_ROWS

    每个不同的值的行的范围内的平均数量。

  • DISTINCT_RANGE_ROWS

    指定不同的键值里面还有多少这个范围内(不包括前的前一个关键RANGE_HI_KEYRANGE_HI_KEY本身);

通常情况下,人口最多的价值观进入RANGE_HI_KEY

然而,他们可以进入的范围,这可能导致在分布的偏斜。

想象一下,这些数据(其中包括其他):

行的关键值计数

1          1
2          1
3          10000
4          1

SQL Server通常建立两个范围: 134至下一个填充的值,这使得这些统计:

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和索引访问是太贵了。



Answer 2:

它使用的统计数据,它保持每个索引。

(您也可以创建非索引列的统计信息)

要更新数据库中的每个表中所有的统计数据( 警告 :将在非常大的数据库一段时间,不要没有你的DBA检查做生产服务器上...。):

exec sp_msforeachtable 'UPDATE STATISTICS ?'

如果你没有定期计划的作业重建最活跃的指标(即手插入或删除的),你应该考虑重建索引时(相同的警告与上述适用):

exec sp_msforeachtable "DBCC DBREINDEX('?')"
  • 通过查询优化器在Microsoft SQL Server 2008中使用的统计信息


Answer 3:

既然你已经更新了统计,我想尝试,以消除任何参数嗅探:

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


Answer 4:

重建的索引可能解决不正确的估计行值问题



文章来源: How does SQL server work out the estimated number of rows?