Embora eu, como o @Thomas, concorde completamente com o @Aaron nos comentários sobre a questão de que o "uso da CPU por banco de dados" seja preciso ou útil, posso pelo menos responder à pergunta de por que essas duas consultas são tão diferente. E a razão pela qual eles são diferentes indicará qual é mais preciso, embora esse nível mais alto de precisão ainda seja relativo àquele que é especificamente impreciso, portanto ainda não é verdadeiramente preciso ;-).
A primeira consulta usa sys.dm_exec_query_stats para obter informações da CPU (por exemplo total_worker_time
). Se você for para a página vinculada que é a documentação do MSDN para essa DMV, você verá uma introdução curta de três frases e duas dessas frases nos fornecerão o que precisamos para entender o contexto dessas informações ("quão confiável é" e "como ele se compara a sys.sysprocesses
"). Essas duas frases são:
Retorna estatísticas de desempenho agregadas para planos de consulta em cache no SQL Server. ... Quando um plano é removido do cache, as linhas correspondentes são eliminadas dessa visualização
A primeira frase, "Retorna estatísticas agregadas de desempenho", informa que as informações nesta DMV (assim como várias outras) são cumulativas e não são específicas apenas para consultas atualmente em execução. Isso também é indicado por um campo na DMV que não faz parte da consulta na Pergunta execution_count
, que novamente mostra que esses são dados cumulativos. E é muito útil que esses dados sejam cumulativos, pois você pode obter médias etc. dividindo algumas das métricas peloexecution_count
.
A segunda frase, "os planos que estão sendo removidos do cache também são removidos desta DMV", indica que não é uma imagem completa, especialmente se o servidor já tiver um cache de plano bastante completo e estiver sob carga e, portanto, expirar os planos. com alguma frequência. Além disso, a maioria das DMVs é redefinida quando o servidor é redefinido para que não seja um histórico verdadeiro, mesmo que essas linhas não tenham sido removidas quando os planos expirarem.
Agora vamos contrastar o acima com sys.sysprocesses
. Essa visualização do sistema mostra apenas o que está em execução no momento, assim como a combinação de sys.dm_exec_connections , sys.dm_exec_sessions e sys.dm_exec_requests (indicado na página vinculada de sys.dm_exec_sessions
). Essa é uma visão totalmente diferente do servidor em comparação com osys.dm_exec_query_stats
DMV, que mantém os dados mesmo após a conclusão do processo. Ou seja, em relação ao "os resultados da segunda consulta estão errados?" pergunta, eles não estão errados, apenas dizem respeito a um aspecto diferente (ou seja, período de tempo) das estatísticas de desempenho.
Portanto, a consulta usando sys.sysprocesses
está apenas olhando "agora". E a consulta usando sys.dm_exec_query_stats
está olhando principalmente (talvez) o que aconteceu desde a última reinicialização do serviço SQL Server (ou obviamente a reinicialização do sistema). Para a análise geral de desempenho, parece que sys.dm_exec_query_stats
é muito melhor, mas, novamente, descarta informações úteis o tempo todo. E, nos dois casos, você também precisa considerar os pontos apresentados pelo @Aaron nos comentários da pergunta (desde que removidos) em relação à precisão do valor "database_id" em primeiro lugar (ou seja, ele reflete apenas o banco de dados ativo que iniciou o código , não necessariamente onde o "problema" está ocorrendo).
Mas, se você só precisa / quer ter uma noção do que está acontecendo agora em todos os bancos de dados, possivelmente porque as coisas estão a abrandar agora, você é melhor fora de usar a combinação de sys.dm_exec_connections
, sys.dm_exec_sessions
e sys.dm_exec_requests
(e não a obsoleta sys.sysprocesses
). Lembre-se de que você está procurando / para consultas , não bancos de dados , porque as consultas podem se unir em vários bancos de dados, incluir UDFs de um ou mais bancos de dados, etc.
EDIT:
Se a preocupação geral é reduzir os consumidores de CPU alta, procure as consultas que ocupam mais CPU, porque os bancos de dados na verdade não ocupam CPU (a procura por banco de dados pode funcionar em uma empresa de hospedagem onde cada banco de dados está isolado e de propriedade de um cliente diferente).
A consulta a seguir ajudará a identificar consultas com alto uso médio da CPU. Condensa os dados no DMV query_stats, pois esses registros podem mostrar a mesma consulta (sim, o mesmo subconjunto do lote de consultas) várias vezes, cada um com um plano de execução diferente.
;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
em milissegundos?total_worker_time
é " A quantidade total de tempo de CPU, relatada em microssegundos (mas precisa apenas de milissegundos), consumida pelas execuções deste plano desde que ele foi compilado ". Isso ajuda? Isso pode ser facilmente convertido em milissegundos, se é assim que você deseja ver.Ajustei a consulta para divisão por 0 erros e otimizei os nomes das colunas para copiar / colar no Excel.
fonte
Gostei tanto da consulta da CPU
sys.dm_exec_query_stats
que a ampliei. Ele ainda é classificado por CPU, mas adicionei outros totais e porcentagens para obter um melhor perfil de servidor. Isso copia bem no Excel e com formatação condicional de cores nas colunas Porcentagem, os piores números se destacam muito bem. Eu usei a 'Escala de cores graduadas' com 3 cores; uma cor de rosa para valores altos, amarelo para meio, verde para baixo.Eu adicionei um rótulo para o
database id 32676
qual é o banco de dados interno de recursos SQL. Converto tempo de CPU e duração em horas para ter uma melhor noção do uso do tempo.fonte