"Find top 5 queries" 按日期

"Find top 5 queries" by date

我如何运行下面的查询(来自this MSDN article)来确定最差的查询(按CPU时间)但仅限于设定日期?

-- Find top 5 queries
SELECT TOP 5 query_stats.query_hash AS "Query Hash", 
    SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count) AS "Avg CPU Time",
    MIN(query_stats.statement_text) AS "Statement Text"
FROM 
    (SELECT QS.*, 
    SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
    ((CASE statement_end_offset 
        WHEN -1 THEN DATALENGTH(st.text)
        ELSE QS.statement_end_offset END 
            - QS.statement_start_offset)/2) + 1) AS statement_text
     FROM sys.dm_exec_query_stats AS QS
     CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
GROUP BY query_stats.query_hash
ORDER BY 2 DESC;
GO

我们的数据库在最后一天刚刚承受了严重的压力,我们无法找出问题的根源。

我们正在使用 Azure SQL 数据库。

无法从 DMV 获取每天的统计数据。 dm_exec_query_stats 有列 creation_time 和 last_execution_time,这当然可以让您了解发生了什么——但这只是第一次也是最后一次使用该计划。如果计划从计划缓存中删除,统计信息也将丢失,因此如果现在情况好转(并且 "bad" 计划已被更好的计划取代),您可能不再拥有该计划及其统计信息。

该查询显示查询使用的平均值 CPU,因此它不是解决性能问题的完美查询,因为它真的很平均,所以执行次数少的东西在列表中可能非常靠前即使这真的不是问题。我通常使用 total CPU 和 total logical reads 来解决性能问题——但这些是自创建时间以来的总量,这可能是很久以前的事了。在这种情况下,您还可以考虑将数字除以自创建时间以来的小时数,这样您将得到平均每小时 CPU / I/O。同时查看 max* 列可能会为错误的查询/计划提供一些提示。

如果您遇到此类问题,最好将 SQL 安排为一项任务并在某处收集结果。然后,您还可以将其用作比较情况不好时发生的变化的基线。当然,在那种情况下(也可能在其他情况下)你最有可能看到的不仅仅是前 5 名。