在计划缓存中查找开销最大的查询(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 选项不同。计划缓存非常大时查询可能需要几秒;安全。