Misurare il tempo necessario per eseguire una query t-sql


156

Ho due query t-sql usando SqlServer 2005. Come posso misurare quanto tempo impiega ciascuna a funzionare?

L'uso del mio cronometro non lo taglia.


2
Stai usando Sql Server Management Studio? In genere visualizza il tempo trascorso per ogni query, anche se solo con una seconda risoluzione. Si veda anche questa domanda correlata: stackoverflow.com/questions/8247587/...
mellamokb

Risposte:


174

Un approccio semplicistico alla misurazione del "tempo trascorso" tra gli eventi è quello di prendere semplicemente la data e l'ora correnti.

In SQL Server Management Studio

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

Per calcolare i tempi trascorsi, è possibile acquisire quei valori di data in variabili e utilizzare la funzione 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;

Questo è solo un approccio. È inoltre possibile ottenere tempi trascorsi per le query utilizzando SQL Profiler.


Ho cercato il documento di SQL Profiler su come eseguire questa operazione, ma non sono riuscito a trovare un documento che non richiedesse ore di lettura. Puoi consigliare un link "Profiler for Dummies"?
TheMoot,

@TheMoot So di essere in ritardo ma i collegamenti MSDN sono perfetti per le tue esigenze "[Subject] for Dummies" :). Prova a dare un'occhiata a questo How To: Usa SQL Profiler
John Odom

Qualcun altro ha avuto problemi con l'utilizzo di questo in sql management studio? L'ho aggiunto a una serie di circa 15 query in una procedura memorizzata per i test e l'esecuzione richiede troppo tempo. Ho annullato a 7 minuti e tutti i timer aggiunti erano solo circa 2 minuti. Quindi penso che ci sia qualche problema con la cache del testo di ritorno o forse ci vuole troppo tempo per calcolare tutti gli appuntamenti per così tanti.
MH,

2
@Hanoncs: c'è un piccolo lasso di tempo usato per valutare GETDATE () e assegnare il risultato a una variabile, e un piccolo lasso di tempo per valutare DATEDIFF () e restituire il risultato. L'approccio semplicistico che ho proposto era di ottenere una misurazione approssimativa per le query singleton. Non consiglierei di usare questo approccio in un ciclo ristretto in una procedura memorizzata. Se avessi una serie di query in una procedura memorizzata, potrei usare questo approccio per aggiungere un output di debug in alcuni punti critici, aggiungendo una colonna discriminatore in modo da poter sapere quale riga nella procedura ha emesso quale risultato.
spencer7593,

1
Di solito rimango SET @t1 = GETDATE();nella parte superiore della mia query e quindi incolla SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();in punti ragionevoli all'interno della query (modificando "NOTA 1" in modo appropriato). Trattare le selezioni come punti di interruzione piuttosto che misurazioni è semanticamente identico al proprio approccio (sebbene il set finale su @ t1 sia spurio e questo presuppone che tutte le query debbano essere misurate). Questa è puramente un'ottimizzazione mentale / tipizzante (un incolla per breakpoint, anziché due paste per query).
Brian,

251

Se vuoi una misurazione più accurata della risposta sopra:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

I risultati saranno nella finestra Messaggi .

Aggiornamento (29/07/2015):

A grande richiesta, ho scritto uno snippet di codice che è possibile utilizzare per eseguire un'intera procedura memorizzata anziché i suoi componenti. Anche se questo restituisce solo il tempo impiegato dall'ultima corsa, ci sono ulteriori statistiche restituite sys.dm_exec_procedure_statsche possono anche essere di valore:

-- 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)

2
Nota solo che questa funzione non è disponibile se l'accesso al database è di sola lettura. To use SET STATISTICS TIME, users must have the appropriate permissions to execute the Transact-SQL statement. The SHOWPLAN permission is not required. da: technet.microsoft.com/en-us/library/ms190287.aspx
Rob

5
C'è un modo in cui posso vedere tutto il tempo che una procedura memorizzata deve eseguire? In questo momento vedo molte misurazioni singole.
Rookian

2
@Rookian, ho aggiunto del codice alla risposta per aiutarti.
Michael Goldshteyn il

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]

Puoi anche vedere questa soluzione


9
Ciò dà il tempo in nanosecondi. Millesecondi sarebbe DATEDIFF (MS, @ StartTime, @ EndTime)
d512

11

Un altro modo consiste nell'utilizzare una funzionalità integrata di SQL Server denominata Client Statisticsaccessibile tramite Menu> Query> Includi statistiche client .

È possibile eseguire ciascuna query in una finestra di query separata e confrontare i risultati forniti nella Client Statisticsscheda accanto alla Messagesscheda.

Ad esempio, nell'immagine seguente mostra che il tempo medio trascorso per ottenere la risposta del server per una delle mie query è di 39 millisecondi.

Risultato

Puoi leggere tutti e 3 i modi per acquisire i tempi di esecuzione qui . Potrebbe anche essere necessario visualizzare Estimated Execution Plan ctrlLper ulteriori indagini sulla query.


7

ancora meglio, questo misurerà la media di n iterazioni della tua query! Ottimo per una lettura più accurata.

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

4
Ho cambiato il MICROSECONDdi MILLISECONDe per cancellare la cache di ogni ho inserito seguenti linee tra begine declare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Funziona come il fascino e esattamente quello che stavo cercando. +1
Daniel Z.

1
Ho usato il tuo frammento per misurare le prestazioni incrementali in una procedura memorizzata, molto liscia!
JayJay

Grazie ad entrambi. Faccio sql da molto tempo ormai, è un linguaggio bizzarro. Ma una volta che sai quali sono i nodi e come farli girare a tuo vantaggio, bene aiuta molto XD
HumbleWebDev

3

Fare clic sull'icona Statistiche per visualizzare, quindi eseguire la query per ottenere i tempi e sapere quanto è efficiente la query

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.