针对sys.tables / sys.dm_db_index_usage_stats查询缓慢

时间:2018-09-04 11:33:05

标签: sql-server

在一个应用程序中,我正在维护以下查询:

SELECT '[mydb].[dbo].[' + [name] + ']' AS TableName,
    COALESCE(MAX(sys.dm_db_index_usage_stats.last_user_update), 
CONVERT(DATETIME, DATEDIFF(dd, 0, GETDATE()))) AS LastUpdate
FROM [mydb].sys.tables AS databaseTables
LEFT JOIN sys.dm_db_index_usage_stats
    ON databaseTables.object_id = sys.dm_db_index_usage_stats.object_id
        AND sys.dm_db_index_usage_stats.index_id IN (0, 1)
GROUP BY '[mydb].[dbo].[' + [name] + ']'

这个想法似乎是,如果LastUpdate时间不大于上一次查询,则可以使用缓存的值,否则可能要执行更昂贵的操作,并且缓存将被替换为结果。

现在通常这似乎很好用,但是在某些客户上,我注意到动作之间存在很大的滞后。 SQL Profiler向我展示了此查询大约需要2秒钟,并且具有数千次读取,而通常仅需要100次读取和5ms。重新启动服务器后问题通常消失了,并且总体上很少发生。

虽然我不太喜欢这种方法,但要更改它并不容易。因此,我有两个问题:为什么有时有时表现不佳,但有时却如此?我什至可以确保实时获得结果,还是dm_db_index_usage_stats是异步更新的?

我无法(至少不能可靠地)重现该问题。有时,它会在应用程序中发生,但是当我执行相同的查询并在SQL Server Management Studio中执行该查询时,该查询将以预期的速度运行。我已经检查了这是否与连接设置有关,但它们似乎相同。我曾经能够在Management Studio中对其进行复制,但是由于我不了解执行计划,因此从那时起就无法在Management Studio中对其进行复制。任何帮助将不胜感激!

到目前为止,此问题已在SQL Server 2016和2017上出现。

1 个答案:

答案 0 :(得分:0)

我发现 JTL Wawi 存在类似问题,它使用完全相同的查询。 UPDATE STATISTICS sys.*** WITH FULLSCAN; 在所有“sys”表上为我们解决了这个问题。