统计--追踪数据更新情况

 背景: 在统计自动更新设置为ON时(默认设置),当更新次数达到一定阀值后便会触发自动更新。

本文通过一些测试来探究SQL SERVER 如何追踪数据更新情况和如何计算更新次数。

--==========================================
--可以使用以下系统表来查看列变化情况
--sys.system_internals_partition_columns
--sys.sysindexes
--sys.sysrscols(需要使用DAC)
--==========================================
--生成测试表和索引
DROP TABLE dbo.TB001
GO
CREATE TABLE dbo.TB001
(
   ID INTIDENTITY(1,1) NOT NULL,
   C1 INT,
   C2 INT
)
GO
ALTER TABLE dbo.TB001
ADD CONSTRAINT PK_TB001
PRIMARY KEY(ID)
GO
CREATE INDEX IX_C2 ON dbo.TB001(C1)
--===========================================
--插入10 条数据
INSERT INTO TB001(C1,C2)
SELECT 1,1
GO 10
--============================================
--数据修改不会即时更新到系统表中,需要使用CHECKPOINT
--来将更新flush到系统表中
CHECKPOINT
GO
--============================================
--使用sys.system_internals_partition_columns来
--查看数据的变更(无法获得非聚簇索引上的变化)
SELECT
    p.[object_id],
    p.[index_id],
    pc.[partition_column_id],
    pc.[modified_count]
FROM sys.system_internals_partition_columns pc
JOIN sys.partitions p
    ON pc.[partition_id] = p.[partition_id]
WHERE p.[object_id] = OBJECT_ID('dbo.TB001');
GO

--================================================
--查看非聚簇索引上的变化
SELECT I.name,I.rowcnt,I.rowmodctr
FROM sys.sysindexes I
WHERE I.id=OBJECT_ID('dbo.TB001');

--================================================
--重建索引
ALTER INDEX [PK_TB001] ON [dbo].[TB001] REBUILD
GO
ALTER INDEX [IX_C2] ON [dbo].[TB001] REBUILD
GO
--===============================================
--重建索引后发现被索引的列的值没有发生变化
SELECT
    p.[object_id],
    p.[index_id],
    pc.[partition_column_id],
    pc.[modified_count]
FROM sys.system_internals_partition_columns pc
JOIN sys.partitions p
    ON pc.[partition_id] = p.[partition_id]
WHERE p.[object_id] = OBJECT_ID('dbo.TB001');
GO

 --================================================
--查看非聚簇索引上的变化
--重建索引后,索引变化rowmodctr的值被清零
SELECT I.name,I.rowcnt,I.rowmodctr
FROM sys.sysindexes I
WHERE I.id=OBJECT_ID('dbo.TB001');
GO

--================================
--对一行数据更新110 遍
UPDATE TB001
SET C1=2
WHERE ID=1
GO 110
CHECKPOINT
--================================================
--查看非聚簇索引上的变化
--发现单行数据被修改110 次,rowmodctr被置为 110
--即使值未发生变化,也被记录为一次修改
 
SELECT I.name,I.rowcnt,I.rowmodctr
FROM sys.sysindexes I
WHERE I.id=OBJECT_ID('dbo.TB001');
GO

--==============================
--更新统计
sp_updatestats
--================================================
--查看非聚簇索引上的变化
--统计被更新后,rowmodctr被重置为0
SELECT I.name,I.rowcnt,I.rowmodctr
FROM sys.sysindexes I
WHERE I.id=OBJECT_ID('dbo.TB001');
GO

使用脚本查看

--查看最后统计更新的时间及最后一次更新后数据更新的次数
SELECT  T.[name] AS TableName ,
        S.[name] AS StatsName ,
        P.last_updated AS LastUpdatedTime ,
        P.[rows] AS TableRows ,
        P.rows_sampled AS SampledRows ,
        P.modification_counter AS ModifiedRows
FROM    sys.tables T
        INNER JOIN sys.stats S ON T.[object_id] = S.[object_id]
        OUTER APPLY sys.dm_db_stats_properties(S.[object_id], s.[stats_id]) AS P
--WHERE T.[name]=''

总结:
1. 使用sys.system_internals_partition_columns来查看聚簇索引上的更新次数
2. 使用sys.sysindexes来查看非聚簇索引上的更新次数
3. 重建索引会导致更新次数数据被重置为零(建议在索引重建后更新统计)
4. 更新次数计算的是更新操作的次数(即使值未发生变化,也被记录为一次修改)
5. 在统计被更新后,更新次数被重置为零

参考链接:http://www.sqlskills.com/blogs/paul/how-are-per-column-modification-counts-tracked/

照例来张图:

原文地址:https://www.cnblogs.com/TeyGao/p/3553996.html