sql server2016的统计信息自动更新尝试

理论

参考:https://docs.microsoft.com/zh-cn/sql/relational-databases/statistics/statistics?view=sql-server-2016
在这里插入图片描述

试验

前提及说明

表的创建、索引定义
drop table op_param_sniffing
-- 表定义,及数据插入
create table op_param_sniffing (
	id bigint IDENTITY(1,1) primary key not null,
	product_id varchar(100) not null,
	product_name varchar(100) not null
)
-- 索引
create index idx_op_param_sniffing_product_id on op_param_sniffing(product_id)
sql1:查询统计信息 上次更新事件、修改次数
SELECT  name, sp.*  
FROM sys.stats AS stat   
CROSS APPLY sys.dm_db_stats_properties(stat.object_id, stat.stats_id) AS sp  
WHERE stat.object_id = object_id('op_param_sniffing');  

在这里插入图片描述

sql2:插入新的数据列

插入5条记录

declare @id int;
set @id = 0;
while @id < 5
begin
	insert into op_param_sniffing(product_id, product_name) values('300', '商品300')
	set @id = @id + 1
end

试验1:先创建索引,再插入数据,发现一直不会更新

使用sql2一直插入500行,使用sql1得到下面,即还没有更新
在这里插入图片描述
后面尝试到添加到600行,也没有更新,怀疑是该索引没有被使用到,所有没有更新
在这里插入图片描述

试验2:统计信息首次有数据

drop table op_param_sniffing
-- 表定义,及数据插入
create table op_param_sniffing (
	id bigint IDENTITY(1,1) primary key not null,
	product_id varchar(100) not null,
	product_name varchar(100) not null
)
-- 先插入一条记录
insert into op_param_sniffing(product_id, product_name) values('300', '商品300')
-- 索引
create index idx_op_param_sniffing_product_id on op_param_sniffing(product_id)

在这里插入图片描述
即:表中有1条数据后再建立索引,自动建立的统计信息非null

试验2:数据不断增多,统计信息更新

在这里插入图片描述
修改数已到阈值500,但没有更新,尝试使用下索引的sql,再查看统计信息:
在这里插入图片描述
即当n <= 500时,更新阈值为500,到达阈值后,当使用到该统计信息时,会触发统计信息的更新;
在这里插入图片描述

试验3:n > 500时的统计信息更新

现在n=501
在这里插入图片描述
即 min (500 + 501 * 0.2), sqrt(1000 * 501)) = min (600.2, 707.81) = 600.2
插入600条数据,看统计信息:
在这里插入图片描述
发现没有更新,再插入1条数据:
在这里插入图片描述
发现600.2即601为阈值,使用到统计信息时,会触发统计信息更新;

试验4:继续增大数据,验证公式是否正确

n = 1102, 即 min (500 + 1102 * 0.2), sqrt(1000 * 1102)) = min (720.4, 1049.76) = 720.4, 故阈值为721.

插入720条、再插入1条,分别查看统计信息更新情况:
在这里插入图片描述
发现阈值并不是721,说明带小数的时候不一定是往上取!!!!!

继续试验的结果

  1. n = 1822, min (500 + 1822 * 0.2), sqrt(1000 * 1822)) = 864.4, 实际阈值865
  2. n = 2687, min (500 + 2687 * 0.2), sqrt(1000 * 2687)) = 1037.4,实际1037
  3. n = 3724, min (500 + 3724* 0.2), sqrt(1000 * 3724)) = 1244.8,实际1244

结论

上面只是进行部分测试,边界值可以自己采用类似方法进行。表的统计信息的更新规则:

  1. n <= 500, 阈值为500;
    2)n > 500, 公式min (500 + 0.2n, sqrt(1000 * n)), 对于小数的情况可能向下取整,也可能向上取整(其实统计信息更新需要时间,上面的向上取整的情况可能有误,详细的可以自己进行多次试验,实际情况下,应该也不会介意1的误差)
    3)达到阈值后,可能不会立即更新,但若调用使用该统计信息的sql,会触发更新;

说明:
上面试验在ssms 2016环境,兼容级别为130,并且打开了自动更新
在这里插入图片描述

插入数据到501行,修改数为500时,统计信息还是没更新
在这里插入图片描述

num < 6时,阈值为6,插入6条记录,再查看统计信息情况:

declare @id int;
set @id = 0;
while @id < 6
begin
	insert into op_param_sniffing(product_id, product_name) values('300', '商品300')
	set @id = @id + 1
end
-- 查看统计信息
select count(*) from op_param_sniffing

SELECT  name, sp.*  
FROM sys.stats AS stat   
CROSS APPLY sys.dm_db_stats_properties(stat.object_id, stat.stats_id) AS sp  
WHERE stat.object_id = object_id('op_param_sniffing'); 

在这里插入图片描述
即达到阈值后,并不会更新统计信息。再插入一条记录

insert into op_param_sniffing(product_id, product_name) values('300', '商品300')

-- 查看统计信息
select count(*) from op_param_sniffing

SELECT  name, sp.*  
FROM sys.stats AS stat   
CROSS APPLY sys.dm_db_stats_properties(stat.object_id, stat.stats_id) AS sp  
WHERE stat.object_id = object_id('op_param_sniffing'); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值