专注,勤学,慎思。戒骄戒躁,谦虚谨慎

just do it

导航

< 2025年2月 >
26 27 28 29 30 31 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 1
2 3 4 5 6 7 8

统计

SQLServer 2016之后的触发统计信息自动更新阈值算法变化

背景:最近trouble shooting某数据库性能问题,发现统计信息相关的一些信息,跟以往“经验”是不吻合的,在以往的知识中,统计信息不应该这么频繁的更新啊

 

之前吐槽了很多年的统计信息自动更新阈值算法(操蛋的500 + (0.20 * n)),其实早在SQLServer 2016中就有优化过了,一直没有注意这个细节,汗颜!

https://www.cnblogs.com/wy123/p/5875237.html
https://www.cnblogs.com/wy123/p/5790855.html

参考官方文档:https://learn.microsoft.com/en-us/sql/relational-databases/statistics/statistics?view=sql-server-ver16

 

最显著的变化,在SQLServer 2016之后,表行数大于500之后:MIN ( 500 + (0.20 * n), SQRT(1,000 * n) ),也即取原算法和1000倍的二次方根的最小值,作为触发阈值。

Table typeTable cardinality (n)Recompilation threshold (# modifications)
Temporary n < 6 6
Temporary 6 <= n <= 500 500
Permanent n <= 500 500
Temporary or permanent n > 500 MIN ( 500 + (0.20 * n), SQRT(1,000 * n) )

根据上述算法,可以发现,
1,算法修改之前,触发统计信息自动更新的值,是随着表的行数的变化为一条严格的一次函数500 + (0.20 * n)
2,算法修改之后,触发统计信息自动更新的值,对于这个计算公式MIN ( 500 + (0.20 * n), SQRT(1,000 * n) ,可以得知:在表的行数超过200W之后,会采用SQRT(1,000 * n)这一新的算法
3,算法修改之后,统计信息自动更新阈值的算法SQRT(1,000 * n)是一条随着表的行数的变化,波动率较低的曲线,也就是意味着更倾向于在一个较小的变化之后触发统计信息自动更新。
4,二次方根(SQRT)是一个非常有魔力的计算规则!!!

 

根据 500 + (0.20 * n),和SQRT(1,000 * n) 两个公式计算出来触发统计信息自动更新的阈值

 

posted on   MSSQL123  阅读(67)  评论(3编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
历史上的今天:
2018-09-14 Redis安全以及备份还原
2018-09-14 Redis物理文件结构
2018-09-14 Redis的Errorlog或者启动日志(错误日志)的配置
点击右上角即可分享
微信分享提示