SQL索引统计信息过期_统计信息更新策略

1次阅读

统计信息过期是索引失效的隐蔽主因,需依据响应延迟、预估偏差、更新超期三类信号及时更新;应启用异步自动更新、禁用 STATISTICS_NORECOMPUTE、针对性手动更新并纳入监控告警。

SQL 索引统计信息过期_统计信息更新策略

统计信息过期是索引“看似存在却不起作用”的最隐蔽原因之一——执行计划里显示 key 为 NULLtype = ALL,或 count(*) 结果来回跳变 ,往往不是代码写错了,而是优化器“看花了眼”。更新策略不能只靠“想起来就跑一下”,得有节奏、有依据、有兜底。

什么时候必须更新?盯住这三类信号

• 查询响应时间突然明显变长,尤其原本毫秒级的简单 WHERE 变成秒级,且执行计划出现“聚集索引扫描”或“堆扫描”;
• 同一查询多次执行,EXPLAIN 或 SQL Server 的 SET STATISTICS XML ON 显示行数预估严重偏离实际(比如预估 100 行,实际返回 50 万);
DBCC SHOW_STATISTICS 查看统计信息最后更新时间,发现距今已超 7 天,且该表近期有大批量 INSERT/DELETE/UPDATE(如日增删改 > 表总行数 10%)。

自动更新不是万能,要调对开关

SQL Server 默认开启 自动更新统计信息(AUTO_UPDATE_STATISTICS),但它只在满足“修改行数阈值”时触发:对于小表(≤ 500 行),改 500 行就更新;对于大表(> 500 行),需修改 ≥ 500 + 20% 当前行数。这意味着一张千万级表,要改满 200 万行才触发——业务等不起。
建议:
• 对核心高频表,显式启用 异步自动更新(AUTO_UPDATE_STATISTICS_ASYNC = ON),避免查询被阻塞;
• 禁用 STATISTICS_NORECOMPUTE(即设为 OFF),确保自动机制不被关闭;
• 不要依赖默认阈值,对关键表单独配置更激进的更新策略。

手动更新要精准,别全库扫

定期全库执行 UPDATE STATISTICS WITH FULLSCAN 效率低、IO 压力大,且可能覆盖掉刚生成的优质采样统计。
更优做法:
• 针对性更新:只更新近期变动大的表,例如 UPDATE STATISTICS Orders WITH SAMPLE 30 PERCENT
• 按需全量采样:对数据分布极不均匀的列(如状态字段、分区键),用 FULLSCAN 确保精度;
• 配合重建索引:执行 ALTER INDEX …… REBUILD 时,默认会更新关联统计信息,可一并完成维护。

把更新变成可监控的日常动作

• 在维护计划中加入“统计信息健康检查”步骤:查询 sys.dm_db_stats_properties,筛选 modification_counter > 100000last_updated < DATEADD(day, -3, GETDATE()) 的统计对象;
• 对更新操作加日志:记录表名、统计名、采样方式、耗时,便于回溯性能波动;
• 设置告警:当某张核心表的统计信息超过 48 小时未更新,自动通知 DBA。

text=ZqhQzanResources