DBAtlas · 数据库运维图谱

在计划缓存中查找开销最大的查询(CPU、读取、持续时间)

SQL Server性能

命令

SELECT TOP (20)
       qs.query_hash,
       SUM(qs.execution_count)                                       AS execs,
       SUM(qs.total_worker_time) / 1000                              AS total_cpu_ms,
       SUM(qs.total_worker_time) / SUM(qs.execution_count) / 1000    AS avg_cpu_ms,
       SUM(qs.total_elapsed_time) / SUM(qs.execution_count) / 1000   AS avg_ms,
       SUM(qs.total_logical_reads) / SUM(qs.execution_count)         AS avg_reads,
       SUM(qs.total_grant_kb) / SUM(qs.execution_count)              AS avg_grant_kb,
       COUNT(DISTINCT qs.query_plan_hash)                            AS plan_count,
       MAX(qs.last_execution_time)                                   AS last_exec,
       MIN(SUBSTRING(st.text, qs.statement_start_offset / 2 + 1,
           ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
             ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) + 1)) AS statement_text,
       MIN(DB_NAME(pa.dbid))                                         AS db
FROM   sys.dm_exec_query_stats qs
  CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
  OUTER APPLY (SELECT CONVERT(int, value) AS dbid FROM sys.dm_exec_plan_attributes(qs.plan_handle)
               WHERE attribute = N'dbid') pa
GROUP BY qs.query_hash
ORDER BY total_cpu_ms DESC;

-- To rank by reads: ORDER BY SUM(qs.total_logical_reads) DESC
-- Plan: SELECT query_plan FROM sys.dm_exec_query_plan(<plan_handle>);

作用

按 query_hash 对计划缓存中的语句分组(仅字面值不同的即席查询合并为一行),返回总的和平均的 CPU、持续时间、逻辑读、内存授予以及计划数。

适用场景

CPU 占满、出现“服务器很慢”投诉、数据库未启用 Query Store,或需要跨所有数据库的服务器级视图时。

注意

只能看到仍在缓存中的计划:计划因重启、DBCC FREEPROCCACHE、内存压力或 RECOMPILE 被逐出的查询不会出现。持久化、按时间窗口的分析请使用 Query Store。plan_count > 1 暗示参数敏感或 SET 选项不同。计划缓存非常大时查询可能需要几秒;安全。

在 DBAtlas 中打开 →

相关内容