我正在使用 Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64) Jun 15 2019 23:15:58 版权所有 (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 (构建 9600
:)我有多个数据库,在高插入/更新表上启用了 CHANGE_TRACKING。我的保留期是 2 天,启用了自动清理。数据库兼容性设置为 130 (SQL 2016)
跟踪的一些表很大,每天可能有数千个插入/更新。这是 change_tracking 表的内容。
这是我们为获取更改而执行的查询示例。
SELECT Columns
FROM CHANGETABLE(CHANGES MyTable, @TrackingKey) AS CT
INNER JOIN MyTable b ON b.Key=CT.Key
WHERE b.Status = 1
我不时看到,获取某些表的最新更改的查询需要很长时间才能完成,并且会产生大量 CPU。为了解决这个问题,我设置了每天晚上运行的更改跟踪表的每日更新统计信息。它有很大帮助,但有时,在用户活跃的日子里,即使在白天,我也必须运行此更新统计信息。当我在这些表上运行更新统计信息时,情况恢复正常,获取最新更改的查询在一段时间内运行良好。
我们对应用程序的某些重要部分使用更改跟踪,因此它必须工作。
是否有任何选项,我可以启用跟踪标志来帮助更改跟踪统计信息?任何有对高活动数据库进行更改跟踪的经验的人都可以给我一些建议吗?
所以我最终决定做一个工作来检查自上次统计更新以来更改跟踪表是否更改了超过 20k 行,然后该作业将更新更改跟踪表上的统计信息。
如果它可以帮助其他人,我会将查询放在这里。此查询为您提供自上次更新统计信息以来表更改超过 20k 次的更改跟踪表的所有统计信息。它为您提供了带有要更新的 object_name 的“更新统计信息”。您只需要在数据库上运行查询结果。我会根据我的工作量对其进行微调,看看 20k 是否是最佳数字。
SELECT
-- st.object_id AS [Table ID]
--, OBJECT_NAME(st.object_id) AS [Table Name]
--, st.name AS [Index Name]
--, STATS_DATE(st.object_id, st.stats_id) AS [LastUpdated]
--, modification_counter AS [Rows Modified]
'UPDATE STATISTICS sys.[' + OBJECT_NAME(st.object_id) + ']' as QueryToRun
FROM sys.stats st
CROSS APPLY sys.dm_db_stats_properties(st.object_id, st.stats_id) AS sp
WHERE OBJECT_NAME(st.object_id) like 'change_t%'
AND OBJECT_NAME(st.object_id) in (SELECT 'change_tracking_' + convert(nvarchar(50),st.object_id) FROM sys.change_tracking_tables ctt inner join sys.tables st ON st.object_id = ctt.object_id inner join sys.schemas ss ON ss.schema_id = st.schema_id)
AND modification_counter > 20000
由于您使用的是具有 DB 兼容模式的 SQL Server 2016,因此 TF 2371 的行为是默认行为。
您应该启用
auto update async
数据库选项,以便当 sql server 更新统计信息时,它不会影响您的工作量。更改此 db 选项是在线操作。您可以做的是利用
sys.dm_db_stats_properties
新的 DMV 来决定是否必须手动更新表的统计信息。您可以将 sql 代理作业配置为每 x 分钟或每小时检查和更新某些关键表的统计信息。你可能会调查这个。Kendra 写了一篇关于变更跟踪性能的文章,它也对我们有所帮助。