Хотя я, как и @Thomas, полностью согласен с @Aaron в комментариях к вопросу, касающемуся вопроса о том, является ли использование ЦП для каждой базы данных точным или полезным, я могу, по крайней мере, ответить на вопрос, почему эти два запроса являются такими разные. И причина, по которой они различаются, укажет, какой из них более точный, хотя этот более высокий уровень точности все еще относительно того, который является конкретно неточным, а значит, и не совсем точным ;-).
Первый запрос использует sys.dm_exec_query_stats для получения информации о процессоре (т.е. total_worker_time). Если вы перейдете на связанную страницу, которая является документацией MSDN для этого DMV, вы увидите краткое введение из 3 предложений и 2 из этих предложений, которые дают нам большую часть того, что нам нужно для понимания контекста этой информации («насколько она надежна») и "как это сравнить с sys.sysprocesses"). Эти два предложения:
Возвращает статистику общей производительности для кэшированных планов запросов в SQL Server. ... Когда план удаляется из кэша, соответствующие строки удаляются из этого представления
Первое предложение «Возвращает статистику производительности агрегата » говорит нам, что информация в этом DMV (как и в некоторых других) является накопительной и не относится только к тем запросам, которые выполняются в данный момент. На это также указывает поле в этом DMV, которое не является частью запроса в Вопросе execution_count, что снова показывает, что это совокупные данные. И очень удобно, чтобы эти данные были кумулятивными, так как вы можете получить средние значения и т. Д. Путем деления некоторых показателей на execution_count.
Второе предложение, «планы, удаляемые из кэша, также удаляются из этого DMV», указывают на то, что это не полная картина вообще, особенно если сервер уже имеет довольно полный кэш планов и находится под нагрузкой и, следовательно, истекает срок действия планов довольно часто. Кроме того, большинство DMV сбрасывается при перезагрузке сервера, поэтому они не являются истинной историей, даже если эти строки не были удалены при истечении срока действия планов.
Теперь давайте сопоставим с sys.sysprocesses. Это системное представление показывает только то, что в данный момент выполняется, точно так же, как сочетание sys.dm_exec_connections , sys.dm_exec_sessions и sys.dm_exec_requests (что указано на связанной странице для sys.dm_exec_sessions). Это совершенно другой взгляд на сервер по сравнению с sys.dm_exec_query_statsDMV, в котором хранятся данные даже после завершения процесса. Это означает, что «результаты второго запроса неверны?» вопрос, они не ошибаются, они просто относятся к другому аспекту (то есть временные рамки) статистики производительности.
Таким образом, запрос с использованием sys.sysprocessesтолько смотрит "прямо сейчас". И в запросе используется sys.dm_exec_query_statsв основном (возможно) то, что произошло с момента последнего перезапуска службы SQL Server (или, очевидно, перезагрузки системы). Для общего анализа производительности кажется, что sys.dm_exec_query_statsон намного лучше, но опять же, он постоянно сбрасывает полезную информацию. И в обоих случаях вам также необходимо учитывать замечания, сделанные @Aaron в комментариях к вопросу (поскольку они удалены), в первую очередь касающиеся точности значения «database_id» (т. Е. Оно отражает только активную БД, инициировавшую код не обязательно, где "проблема" происходит).
Но, если вам просто нужно / хочу , чтобы получить представление о том , что происходит прямо сейчас во всех базах данных, возможно , потому , что вещи замедляются прямо сейчас, вы лучше использовать комбинацию из sys.dm_exec_connections, sys.dm_exec_sessionsи sys.dm_exec_requests(и не рекомендуется sys.sysprocesses). Просто имейте в виду, что вы просматриваете / ищите запросы , а не базы данных , потому что запросы могут объединяться в несколько баз данных, включая пользовательские функции из одной или нескольких баз данных и т. Д.
РЕДАКТИРОВАТЬ:
если общая проблема заключается в сокращении нагрузки на ЦП, то ищите запросы, которые занимают больше всего ЦП, потому что базы данных фактически не занимают ЦП (поиск по базе данных может работать в хостинговой компании, где каждая база данных изолирована и принадлежит другому клиенту).
Следующий запрос поможет идентифицировать запросы с высокой средней загрузкой ЦП. Он конденсирует данные в DMV query_stats, поскольку эти записи могут показывать один и тот же запрос (да, одно и то же подмножество пакета запроса) несколько раз, каждый с разным планом выполнения.
;WITH cte AS
(
SELECT stat.[sql_handle],
stat.statement_start_offset,
stat.statement_end_offset,
COUNT(*) AS [NumExecutionPlans],
SUM(stat.execution_count) AS [TotalExecutions],
((SUM(stat.total_logical_reads) * 1.0) / SUM(stat.execution_count)) AS [AvgLogicalReads],
((SUM(stat.total_worker_time) * 1.0) / SUM(stat.execution_count)) AS [AvgCPU]
FROM sys.dm_exec_query_stats stat
GROUP BY stat.[sql_handle], stat.statement_start_offset, stat.statement_end_offset
)
SELECT CONVERT(DECIMAL(15, 5), cte.AvgCPU) AS [AvgCPU],
CONVERT(DECIMAL(15, 5), cte.AvgLogicalReads) AS [AvgLogicalReads],
cte.NumExecutionPlans,
cte.TotalExecutions,
DB_NAME(txt.[dbid]) AS [DatabaseName],
OBJECT_NAME(txt.objectid, txt.[dbid]) AS [ObjectName],
SUBSTRING(txt.[text], (cte.statement_start_offset / 2) + 1,
(
(CASE cte.statement_end_offset
WHEN -1 THEN DATALENGTH(txt.[text])
ELSE cte.statement_end_offset
END - cte.statement_start_offset) / 2
) + 1
)
FROM cte
CROSS APPLY sys.dm_exec_sql_text(cte.[sql_handle]) txt
ORDER BY cte.AvgCPU DESC;
AvgCPUв миллисекундах?