MSSQL中统计信息直方图中对于没有覆盖到谓词预估以及预估策略的变化
Tags: MSSQLSQL Server直方图谓词
简介
SQL Server 2012中(包括之前的版本),因表中数据变化,但统计信息尚未更新的情况下,对于直方图中没有覆盖到的谓词过滤时,sqlserver总是预估为1行
SQL Server 2014和 Server 2016中这种估算方式都有所变化,从表现看,对于对于没有覆盖到的谓词过滤的预估,每个版本都是不同的。
本文简单测试一下此种情况在SQL Server 2012,SQL Server 2014,SQL Server 2016的不同表现,以及该问题可能造成的潜在影响。
下面涉及到的测试环境的数据库版本如下
测试环境准备
首先利用如下脚本,建一张测试表,写入测试数据,下面会解释测试数据的分布
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | create table A ( IdentifierId int identity(1,1), Id1 int, Id2 int, OtherCol CHAR(500) ) GO begin tran declare @i int = 1 while @i<=1000000 begin insert into A values ((@i/50000)+1,@i,NEWID()) set @i = @i+1 if (@i%500000)=0 begin if @@TRANCOUNT>0 begin commit begin tran end end end if @@TRANCOUNT>0 begin commit end GO |
插入的测试数据的分布如下,Id1是从1~20,每一个Id1对应50000个不同的Id2
统计信息直方图中覆盖到的谓词的预估
测试:根据直方图中的任何一个Id来做查询,查询之前先创建相关列上的统计信息,发现预估行数是绝对准确的。
查看idx_1上的统计信息,上面预估的绝对准确就归结于统计信息100%的取样统计以及Rang_Hi_key的EQ_Rows,直方图中的Id1的分布是1~21
统计信息直方图中未覆盖到的谓词的预估
继续插入一个与上面Id2都不一样的数据,这里为50,因为此时插入的是50000行数据,同时又不足以触发统计信息更新,因此发生如下写入数据之后,统计信息并不会更新。
因此这个插入完成之后,统计信息并没有更新。
因为统计信息没有更新,在idx_1的直方图中,是没有Id1=50的信息的,也就说Id1=50不存在于统计信息的直方图中,
在SQL Server 2012中预估的结果:预估为1行,实际为50000行
重复以上测试代码,分别在SQL Server 2014和SQL Server 2016中测试,不重复截图了
SQL Server 2014中测试如下:行预估为1024.7,实际为50000,
这个值是通过什么方式计算出来的?暂时还没查到资料。