Самые дорогие запросы в кэше планов (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 (ad-hoc запросы, различающиеся только литералами, сводятся в одну строку) и возвращает суммарные и средние CPU, длительность, логические чтения, предоставление памяти и число планов.
Когда использовать
Когда CPU загружен до предела, при жалобе "сервер тормозит", для баз без Query Store или когда нужен общесерверный обзор по всем базам.
Внимание
Видит только планы, ещё находящиеся в кэше: запросы, чьи планы вытеснены перезапуском, DBCC FREEPROCCACHE, нехваткой памяти или RECOMPILE, отсутствуют. Для постоянного анализа по временным окнам используйте Query Store. plan_count > 1 намекает на чувствительность к параметрам или разные опции SET. При очень большом кэше планов запрос может занять несколько секунд; безопасно.