SQL 服务器 - 按日期"Find top 5 queries"



我如何运行下面的查询(来自这篇MSDN文章)来确定最糟糕的查询(按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,它们当然可以让您了解发生了什么——但这只是第一次和最后一次使用该计划。如果计划从计划缓存中删除,统计数据也会丢失,所以如果情况现在更好("坏"计划被更好的计划所取代),您可能不再拥有该计划及其统计数据。

该查询显示了查询使用的平均CPU,所以它不是解决性能问题的完美查询,因为它实际上是平均的,所以执行计数小的查询在列表中可能非常高,即使它真的不是问题。我通常使用总CPU和总逻辑读取来解决性能问题——但这些是自创建时间以来的总量,可能是很久以前的事情了。在这种情况下,您可能还需要考虑将这些数字除以创建时间以来的小时数,这样您将得到每小时的平均CPU/I/O。另外,查看max*列可能会给糟糕的查询/计划一些提示。

如果你有这样的问题,它可能是一个好主意,调度SQL作为一个任务,并在某处收集结果。然后,你也可以用它作为基线,比较情况不好时发生了什么变化。当然,在这种情况下(也可能是其他情况),你很可能不应该只看前5名。

最新更新