Pergunta

É possível obter uma desagregação de utilização da CPU pelo banco de dados?

Eu estou idealmente procurando um Gerenciador de Tarefas do tipo de interface para o SQL server, mas em vez de olhar para a utilização da CPU de cada PID (como taskmgr) ou cada SPID (como spwho2k5), Quero ver a total utilização da CPU de cada banco de dados.Suponha que uma única instância do SQL.

Eu percebo que as ferramentas poderiam ser escritas, para coletar dados e gerar relatórios, mas eu estou querendo saber se existe alguma ferramenta que me permite ver uma visualização ao vivo de bancos de dados que estão a contribuir mais para o sqlservr.exe A carga da CPU.

Foi útil?

Solução

Uma espécie de.Verifique esta consulta:

SELECT total_worker_time/execution_count AS AvgCPU  
, total_worker_time AS TotalCPU
, total_elapsed_time/execution_count AS AvgDuration  
, total_elapsed_time AS TotalDuration  
, (total_logical_reads+total_physical_reads)/execution_count AS AvgReads 
, (total_logical_reads+total_physical_reads) AS TotalReads
, execution_count   
, 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 txt  
, query_plan
FROM sys.dm_exec_query_stats AS qs  
cross apply sys.dm_exec_sql_text(qs.sql_handle) AS st  
cross apply sys.dm_exec_query_plan (qs.plan_handle) AS qp 
ORDER BY 1 DESC

Isso vai levar você a consultas em cache do plano, a fim de quanto de CPU eles usados.Você pode executar esse periodicamente, como em um trabalho do Agente de SQL, e inserir os resultados em uma tabela para se certificar de que os dados persistir além de ser reiniciado.

Quando você ler os resultados, você provavelmente vai perceber por que nós não podemos correlacionar os dados diretamente para um banco de dados individual.Primeiro, uma única consulta também pode ocultar sua verdadeira base de dados de pai fazendo truques como este:

USE msdb
DECLARE @StringToExecute VARCHAR(1000)
SET @StringToExecute = 'SELECT * FROM AdventureWorks.dbo.ErrorLog'
EXEC @StringToExecute

A consulta deve ser executada no banco de dados, mas os resultados das pesquisas da AdventureWorks.Onde devemos atribuir o consumo de CPU?

Ela fica pior quando você:

  • Junte-se entre vários bancos de dados
  • Executar uma operação em vários bancos de dados, e o fecho esforço se estende a vários bancos de dados
  • Executar trabalhos do SQL Agent no MSDB que "trabalhar" no MSDB, mas fazer backup de bancos de dados individuais

Ele vai sobre e sobre.É por isso que faz sentido para optimizar o desempenho no nível de consulta em vez de a nível de banco de dados.

No SQL Server 2008R2, Microsoft introduziu o gerenciamento de desempenho de aplicações e de gestão de recursos que permitem compactar um banco de dados único em uma distribuível e destacável DAC pack, e eles estão prometendo recursos para tornar mais fácil para gerenciar o desempenho de bancos de dados individuais e suas aplicações.Ele ainda não faz o que você está procurando, no entanto.

Para mais, confira o T-SQL do repositório de Toad Mundo do SQL Server wiki (ex-SQLServerPedia).

Atualizado em 1/29 para incluir o total de números em vez de apenas médias.

Outras dicas

SQL Server (a partir de 2000) vai instalar os contadores de desempenho (visível a partir do Monitor de Desempenho ou Desempenho).

Uma das categorias de contador (a partir de um SQL Server 2005 instalar é:) - SQLServer:Databases

Com uma instância para cada banco de dados.Os contadores disponíveis, no entanto, não fornecem uma CPU % de Utilização de contador ou de algo semelhante, ainda há alguma taxa de contadores, que você pode utilizar para obter uma boa estimativa da CPU.Exemplo seria, se você tem 2 bancos de dados, e a taxa de medição é 20 operações/seg no banco de dados Um e 80 trans/s na base de dados B --- em seguida, você deve saber que Um contribui com cerca de 20% do total de CPU, e B contribui para outros 80%.

Existem algumas falhas aqui, como que assumindo que todo o trabalho que está sendo feito é dependente da CPU, o que, claro, com bancos de dados não.Mas o que seria um começo, que eu acredito.

Aqui está uma consulta que irá mostrar a base de dados real fazendo com que a carga elevada.Ele utiliza a cache de consulta que pode ficar esvaziada com frequência em condições de baixa memória cenários (fazer a pergunta menos útil).

select dbs.name, cacheobjtype, total_cpu_time, total_execution_count from
    (select top 10
        sum(qs.total_worker_time) as total_cpu_time,  
        sum(qs.execution_count) as total_execution_count, 
        count(*) as  number_of_statements,  
        qs.plan_handle
    from  
        sys.dm_exec_query_stats qs 
    group by qs.plan_handle
    order by sum(qs.total_worker_time) desc
    ) a
inner join 
(SELECT plan_handle, pvt.dbid, cacheobjtype
FROM (
    SELECT plan_handle, epa.attribute, epa.value, cacheobjtype
    FROM sys.dm_exec_cached_plans 
        OUTER APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
     /* WHERE cacheobjtype = 'Compiled Plan' AND objtype = 'adhoc' */) AS ecpa 
PIVOT (MAX(ecpa.value) FOR ecpa.attribute IN ("dbid", "sql_handle")) AS pvt
) b on a.plan_handle = b.plan_handle
inner join sys.databases dbs on dbid = dbs.database_id

Eu acho que a resposta para sua pergunta é não.

O problema é que uma atividade em um computador pode causar carregar em vários bancos de dados.Se eu tiver um processo que está lendo a partir de um banco de dados de configuração, fazendo um registro de banco de dados, e movendo-se a transacções em vários DBs com base no tipo, como faço para particionar o uso da CPU?

Você poderia dividir o uso da CPU, a carga de transação, mas que é novamente um áspero métrica que pode enganar você.Como você dividir o log de transação do envio de um banco de dados para outro, por exemplo?É a carga da CPU em que a leitura ou a escrita?

É melhor olhar para a taxa de transação para uma máquina e a carga da CPU que ela causa.Você também pode perfil de procedimentos armazenados e ver se alguma delas estiver a tomar uma quantidade excessiva de tempo;no entanto, este não terá a resposta que você quer.

Com tudo o que disse acima em mente.
Iniciando com o SQL Server 2012 (pode ser de 2008 ?) há coluna database_id no sys.dm_exec_sessions.
Ele nos dá fácil de cálculo de cpu para cada banco de dados para atualmente conectado sessões.Se a sessão de ter desligado e, em seguida, os seus resultados têm ido.

select session_id, cpu_time, program_name, login_name, database_id 
  from sys.dm_exec_sessions 
 where session_id > 50;

select sum(cpu_time)/1000 as cpu_seconds, database_id 
 from sys.dm_exec_sessions 
group by database_id
order by cpu_seconds desc;

Dê uma olhada no O Sentry SQL.Ele faz tudo o que você precisa e muito mais.

Cumprimentos, Lieven

Você já se olhou no SQL profiler?

Tome o padrão "T-SQL" ou "Procedimento Armazenado" modelo, ajustar os campos agrupar por o ID de banco de dados (eu acho que você tem usado o número, você não conseguir o nome do banco de dados, mas é fácil descobrir usando exec sp_databases para obter a lista)

Executar isso por um tempo e você vai obter o total de contagens de CPU / Disco e / s / Wait etc.Isto pode dar-lhe a percentagem de CPU utilizado por cada banco de dados.

Se você monitorar o contador de Desempenho ao mesmo tempo (registo de dados para um banco de dados SQL), e faça o mesmo para o SQL Profiler (log para banco de dados), você pode ser capaz de correlacionar os dois juntos.

Mesmo assim, ele deve dar-lhe o suficiente de uma pista para o que DB é a pena olhar com mais detalhes.Em seguida, fazer o mesmo de novo, apenas com o banco de dados de IDENTIFICAÇÃO e olhar para o mais caro SQL / Procedimentos Armazenados.

por favor, verifique esta consulta:

SELECT 
    DB_NAME(st.dbid) AS DatabaseName
    ,OBJECT_SCHEMA_NAME(st.objectid,dbid) AS SchemaName
    ,cp.objtype AS ObjectType
    ,OBJECT_NAME(st.objectid,dbid) AS Objects
    ,MAX(cp.usecounts)AS Total_Execution_count
    ,SUM(qs.total_worker_time) AS Total_CPU_Time
    ,SUM(qs.total_worker_time) / (max(cp.usecounts) * 1.0) AS Avg_CPU_Time 
FROM sys.dm_exec_cached_plans cp 
INNER JOIN sys.dm_exec_query_stats qs 
    ON cp.plan_handle = qs.plan_handle
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
WHERE DB_NAME(st.dbid) IS NOT NULL
GROUP BY DB_NAME(st.dbid),OBJECT_SCHEMA_NAME(objectid,st.dbid),cp.objtype,OBJECT_NAME(objectid,st.dbid) 
ORDER BY sum(qs.total_worker_time) desc
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top