不正确的 SQL Server 统计信息

Posted

技术标签:

【中文标题】不正确的 SQL Server 统计信息【英文标题】:Improper SQL Server statistics 【发布时间】:2021-12-24 19:24:41 【问题描述】:

我有大表和具有 3 个 int 字段的聚集索引的简单情况。当我使用前 2 个过滤时,估计的行数不正确,因为统计数据显示错误的数字。这是在 SQL Server 2019 CU12 上测试的。所有 SQL Server 版本都存在同样的问题。我测试的最低版本是带有所有服务包的 SQL 2008。

这是我的 SQL 代码(示例)

create table dbo.glp_test (NagId bigint not null, Lp bigint not null,Id bigint not null, opis varchar(200), CONSTRAINT BK_glp_test PRIMARY KEY CLUSTERED(NagId, Lp, id))
GO
create function dbo.genNum(@start int, @end int)
returns @t table (num int not null identity(1,1))
begin
  while @start<=@end
  begin
    insert into @t default values
    set @start = @start+1;
  end

  return;
end
GO
insert into dbo.glp_test (NagId, lp, Id, opis)
select s.Num, c.Num, c.Num*c2.Num, convert(varchar(100), c.Num*c2.Num)
  from dbo.genNum(1,10000) s
  cross apply dbo.genNum(1,30) c
  cross apply dbo.genNum(1,30) c2 
GO
update statistics glp_test with fullscan
GO
dbcc show_statistics('glp_test','BK_glp_test')
GO
-- select [rows]*[All density]
select 9000000*3.333333E-06 -- 29,999997 - correct
GO
update statistics glp_test
GO
dbcc show_statistics('glp_test','BK_glp_test')
GO
-- select [rows]*[All density]
select 9000000*8.609557E-05 -- 774,86013 - dramatically incorrect
GO

现在,如果我使用字段 1 和字段 2 的确切值查询表 glp_test,则估计的行数是错误的。估计应该接近 30。使用全扫描更新统计信息可以解决问题,但这不是解决方案。如何解决这个问题?

declare @Nagid bigint, @Lp bigint
select * from dbo.glp_test where NagID = @NagId and Lp = @Lp

【问题讨论】:

仅供参考,我真的建议不要使用这些功能。众所周知,多行表值函数的性能很差,而带有WHILE 的函数的性能会很糟糕。 函数 genNum 只是技术问题,与统计问题没有任何共同之处 CU13 适用于 SQL Server 2019,也许您遇到的任何错误都可能已经修复。问题可能是统计数据过时,也许更新统计数据可以解决问题? 简单更新统计信息并不能解决问题。只有全扫描可以。由于问题甚至出现在 SQL 2008 中,我认为他们无法在 CU13 中解决它。 【参考方案1】:

我认为这与在没有 WITH FULLSCAN 的情况下运行更新统计信息时发生的默认采样有关。请参阅此link,其中 Joe Sack 在他所做的测试中显示了抽样百分比。请注意,默认采样率大幅下降。

【讨论】:

FULLSCAN 需要更多的时间和资源。从我的角度来看,这听起来像是一个错误,因为我希望前两个字段 (0-30) 的值介于 0 和最大数量之间。任何超过此值的值对于它所采用的任何样本都是无效的。

以上是关于不正确的 SQL Server 统计信息的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 查找统计信息的采样时间与采样比例

SQL SERVER的统计信息

SQL Server 统计信息

全废话SQL Server统计信息——统计信息基础

全废话SQL Server统计信息——统计信息基础

SQL Server统计信息简介