前言: 统计 信息 是关于谓词中的数据分布的主要 信息 源,如果不知道具体的数据分布,优化器不能获得预估的数据集,从而不能 统计 需要返回的数据。 在创建列的 统计 信息 后,在 DML 操作如 insert 、 update 、 delete 后, 统计 信息 就会过时。因为这些
前言:
统计 信息 是关于谓词中的数据分布的主要 信息 源,如果不知道具体的数据分布,优化器不能获得预估的数据集,从而不能 统计 需要返回的数据。
在创建列的 统计 信息 后,在 DML 操作如 insert 、 update 、 delete 后, 统计 信息 就会过时。因为这些操作更改了数据,影响了数据分布。此时需要更新 统计 信息 。
在高活动的表中, 统计 信息 可能几个小时就会过时。对于静态表,可能几个星期才会过时。这要视乎表上 DML 的操作。
从 2000 开始, SQLServer 对增删改操作会增加在表 sysindexes 中的 RowModCtr ( Row Modification Counter )值,当 统计 信息 更新后,该值会重置会 0 ,并重新累加。所以查看这个表的这个值就可以知道 统计 信息 是否过时。
在 2000 之后, SQLServer 改变了这种跟踪方式,把更改存放到对应的数据行上。这个值是未公开的 ColModCtr 。
但是 sys.sysindexes 到 2012 依旧可用,还是可以用这个表的数值来确定是否 过期 。
准备工作:
本文将用到下面的系统视图和兼容性视图:
1、 sys.sysindexes :兼容性视图,提供 RowModCtr 列值,是本文的核心。
2、 sys.indexes :使用表 ID 来获得 统计 信息 名。
3、 sys.objects :获取架构名。
步骤:
显示 RowModCtr 值很高的 统计 信息 :
SELECT DISTINCT OBJECT_NAME(SI.object_id) AS Table_Name , SI.name AS Statistics_Name , STATS_DATE(SI.object_id, SI.index_id) AS Last_Stat_Update_Date , SSI.rowmodctr AS RowModCTR , SP.rows AS Total_Rows_In_Table , 'UPDATE STATISTICS [' + SCHEMA_NAME(SO.schema_id) + '].[' + OBJECT_NAME(SI.object_id) + ']' + SPACE(2) + SI.name AS Update_Stats_Script FROM sys.indexes AS SI( NOLOCK ) INNER JOIN sys.objects AS SO( NOLOCK ) ON SI.object_id = SO.object_id INNER JOIN sys.sysindexes SSI( NOLOCK ) ON SI.object_id = SSI.id AND SI.index_id = SSI.indid INNER JOIN sys.partitions AS SP ON SI.object_id = SP.object_id WHERE SSI.rowmodctr > 0 AND STATS_DATE(SI.object_id, SI.index_id) IS NOT NULL AND SO.type = 'U' ORDER BY RowModCTR DESC
分析:
需要了解一些事情:
1、 从你上次更新 统计 信息 是何时的事情?
2、 在更新 统计 信息 之后有多少事务发生在表上?
3、 哪些 T-SQL 需要用于更新 统计 信息 。
4、 更新 统计 信息 是否可行?这个是对比 RowModCTR 列和 Total_Rows_In_Table 列。
当在数据库开启了 Auto_Update_Statistics 之后,还有数据的话,那就有必要更新 统计 信息 。下面有一些规则:
1、 表大小从 0 增长。
2、 当表的数据小于等于 500 时没有问题,并且 ColModCtr 从超过 500 行之后开始增长。
3、 当表的行数超过 500 行时,在 统计 信息 对象的引导列的 ColModCtr 值超过 500+20% 的行数时,就需要更新。
例子:有一个 100 万行的表,优化器会在插入 200500 行新数据后认为 统计 信息 过时。但是这并不是绝对化的。
扩充知识:
没有直接的方式访问 ColModCtr 的值,因为它只是用于优化引起,并且对用户透明,但是可以使用 DAC( 专用管理员连接 ) 来访问 sys.sysrscols.rcmodified 系统。但是仅在 2008R2 及以后版本才可用。
查看更多关于第十二章SQLServer统计信息(3)发现过期统计信息并处理的详细内容...