Meça o tempo necessário para executar uma consulta t-sql

156

Eu tenho duas consultas t-sql usando o SqlServer 2005. Como posso medir quanto tempo leva para cada uma ser executada?

Usar o cronômetro não é suficiente.

TheMoot
fonte
2
Você está usando o Sql Server Management Studio? Geralmente, exibe o tempo decorrido para cada consulta, embora apenas com a segunda resolução. Veja também esta questão relacionada: stackoverflow.com/questions/8247587/...
mellamokb

Respostas:

174

Uma abordagem simplista para medir o "tempo decorrido" entre os eventos é apenas pegar a data e hora atuais.

No SQL Server Management Studio

SELECT GETDATE();
SELECT /* query one */ 1 ;
SELECT GETDATE();
SELECT /* query two */ 2 ; 
SELECT GETDATE(); 

Para calcular os tempos decorridos, você pode capturar esses valores de data em variáveis ​​e usar a função DATEDIFF:

DECLARE @t1 DATETIME;
DECLARE @t2 DATETIME;

SET @t1 = GETDATE();
SELECT /* query one */ 1 ;
SET @t2 = GETDATE();
SELECT DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;

SET @t1 = GETDATE();
SELECT /* query two */ 2 ;
SET @t2 = GETDATE();
SELECT DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;

Essa é apenas uma abordagem. Você também pode obter tempos decorridos para consultas usando o SQL Profiler.

spencer7593
fonte
Procurei o documento do Sql Profiler sobre como fazer isso, mas não consegui encontrar um documento que não exigisse horas de leitura. Você pode recomendar um link "Profiler for Dummies"?
TheMoot
@TheMoot Eu sei que estou atrasado, mas os links do MSDN são perfeitos para as suas necessidades "[Assunto] para manequins" :). Tente dar uma olhada nisso Como: Usar o SQL Profiler
John Odom
Alguém mais teve problemas em usar isso no sql management studio? Adicionei-o a um conjunto de cerca de 15 consultas em um procedimento armazenado para teste e leva muito tempo para ser executado. Cancelei aos 7 minutos e todos os temporizadores somados foram de apenas 2 minutos. Então, acho que há algum problema de cache de texto de retorno ou talvez demore muito para calcular todos os datados de tantos.
MH
2
@Hanoncs: Há uma pequena quantidade de tempo usada para avaliar GETDATE () e atribuir o resultado a uma variável, e uma pequena quantidade de tempo para avaliar a DATEDIFF () e retornar o resultado. A abordagem simplista que propus foi obter uma medida aproximada para consultas singleton. Eu não recomendaria usar essa abordagem dentro de um loop apertado em um procedimento armazenado. Se eu tivesse uma série de consultas em um procedimento armazenado, talvez usasse essa abordagem para adicionar alguma saída de depuração em alguns pontos criteriosos, adicionando uma coluna discriminadora para saber qual linha do procedimento emitiu qual resultado.
Spencer7593
1
Normalmente, mantenho SET @t1 = GETDATE();a parte superior da minha consulta e SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();colo em pontos criteriosos da consulta (editando "NOTA 1" adequadamente). Tratar as seleções como pontos de interrupção em vez de medições é semanticamente idêntico à sua abordagem (embora o conjunto final para @ t1 seja espúrio e isso pressuponha que todas as consultas devam ser medidas). Isso é puramente uma otimização mental / de digitação (uma pasta por ponto de interrupção, em vez de duas pastas por consulta).
Brian
251

Se você deseja uma medida mais precisa do que a resposta acima:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

Os resultados estarão na janela Mensagens .

Atualização (29/07/2015):

Por solicitação popular, escrevi um trecho de código que você pode usar para cronometrar a execução de um procedimento armazenado inteiro, em vez de seus componentes. Embora isso retorne apenas o tempo gasto na última execução, há estatísticas adicionais retornadas sys.dm_exec_procedure_statsque também podem ter valor:

-- Use the last_elapsed_time from sys.dm_exec_procedure_stats
-- to time an entire stored procedure.

-- Set the following variables to the name of the stored proc
-- for which which you would like run duration info
DECLARE @DbName NVARCHAR(128);
DECLARE @SchemaName SYSNAME;
DECLARE @ProcName SYSNAME=N'TestProc';

SELECT CONVERT(TIME(3),DATEADD(ms,ROUND(last_elapsed_time/1000.0,0),0)) 
       AS LastExecutionTime
FROM sys.dm_exec_procedure_stats
WHERE OBJECT_NAME(object_id,database_id)=@ProcName AND
      (OBJECT_SCHEMA_NAME(object_id,database_id)=@SchemaName OR @SchemaName IS NULL) AND
      (DB_NAME(database_id)=@DbName OR @DbName IS NULL)
Michael Goldshteyn
fonte
2
Apenas observe que essa função não está disponível se o seu acesso ao banco de dados for somente leitura. To use SET STATISTICS TIME, users must have the appropriate permissions to execute the Transact-SQL statement. The SHOWPLAN permission is not required. from: technet.microsoft.com/en-us/library/ms190287.aspx
Rob
5
Existe uma maneira de ver o tempo todo que um procedimento armazenado precisa executar? No momento, vejo muitas medições únicas.
Rookian
2
@Rookian, adicionei algum código à resposta para ajudá-lo.
Michael Goldshteyn
17
DECLARE @StartTime datetime
DECLARE @EndTime datetime
SELECT @StartTime=GETDATE() 

 -- Write Your Query


SELECT @EndTime=GETDATE()

--This will return execution time of your query
SELECT DATEDIFF(MS,@StartTime,@EndTime) AS [Duration in millisecs]

Você também pode ver esta solução

atik sarker
fonte
9
Isso fornece o tempo em nanossegundos. Milésimos de segundo seria DATEDIFF (MS, @ StartTime, @ EndTime)
d512
11

Outra maneira é usar um recurso interno do SQL Server chamado Client Statisticsacessível através de Menu> Consulta> Incluir Estatísticas do Cliente .

Você pode executar cada consulta na janela de consulta separada e comparar os resultados fornecidos na Client Statisticsguia ao lado da Messagesguia.

Por exemplo, na imagem abaixo, mostra que o tempo médio decorrido para obter a resposta do servidor para uma de minhas consultas é de 39 milissegundos.

Resultado

Você pode ler todas as três maneiras de adquirir tempo de execução aqui . Pode ser necessário exibi-lo Estimated Execution Plan ctrlLpara uma investigação mais aprofundada sobre sua consulta.

Mohammad Musavi
fonte
7

melhor ainda, isso medirá a média de n iterações da sua consulta! Ótimo para uma leitura mais precisa.

declare @tTOTAL int = 0
declare @i integer = 0
declare @itrs integer = 100

while @i < @itrs
begin
declare @t0 datetime = GETDATE()

--your query here

declare @t1 datetime = GETDATE()

set @tTotal = @tTotal + DATEDIFF(MICROSECOND,@t0,@t1)

set @i = @i + 1
end

select @tTotal/@itrs
HumbleWebDev
fonte
4
Mudei o MICROSECONDque MILLISECONDe para limpar o cache de cada vez que eu inseri seguinte linhas entre begine declare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Funciona como charme e exatamente o que eu estava procurando. 1
Daniel Z.
1
Eu tenho usado o snippet de ano para medir ajustes incrementais de desempenho em um procedimento armazenado, muito liso!
precisa saber é o seguinte
Obrigado a ambos. Estou fazendo sql há muito tempo, é uma linguagem peculiar. Mas uma vez que você sabe quais são as torções e como colocá-los para a sua vantagem, bem isso ajuda XD muito
HumbleWebDev
3

Clique no ícone Estatísticas para exibir e, em seguida, execute a consulta para obter os horários e saber a eficiência da sua consulta.

Ashish Patel
fonte