Zmierz czas potrzebny na wykonanie zapytania t-sql


156

Mam dwa zapytania t-sql przy użyciu SqlServer 2005. Jak mogę zmierzyć, ile czasu zajmuje wykonanie każdego z nich?

Korzystanie ze stopera nie wystarcza.


2
Czy używasz Sql Server Management Studio? Zwykle wyświetla czas, który upłynął dla każdego zapytania, aczkolwiek tylko z drugim rozwiązaniem. Zobacz także to powiązane pytanie: stackoverflow.com/questions/8247587/ ...
mellamokb

Odpowiedzi:


174

Jednym z uproszczonych sposobów mierzenia „czasu, który upłynął” między zdarzeniami jest po prostu pobranie aktualnej daty i godziny.

W SQL Server Management Studio

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

Aby obliczyć upływ czasu, możesz pobrać te wartości dat do zmiennych i użyć funkcji 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;

To tylko jedno podejście. Czas, jaki upłynął, można również uzyskać dla zapytań za pomocą programu SQL Profiler.


Szukałem dokumentu Sql Profiler o tym, jak to zrobić, ale nie mogłem znaleźć dokumentu, który nie wymagałby godzin czytania. Czy możesz polecić link „Profiler for Dummies”?
TheMoot

@TheMoot Wiem, że się spóźniłem, ale linki MSDN są idealne dla Twoich potrzeb „[Temat] dla opornych” :). Spróbuj przyjrzeć się poniższemu poradnikowi: Korzystanie z programu SQL Profiler
John Odom

Czy ktoś inny miał problemy z używaniem tego w SQL Management Studio? Dodałem go do zestawu około 15 zapytań w procedurze składowanej na potrzeby testowania, a jego uruchomienie trwa zbyt długo. Anulowałem po 7 minutach, a wszystkie liczniki zsumowane to tylko około 2 minuty. Więc myślę, że jest jakiś problem z pamięcią podręczną tekstu zwrotnego, a może obliczenie wszystkich dat dla tak wielu trwa zbyt długo.
MH

2
@Hanoncs: Jest niewielka ilość czasu wykorzystywana do obliczenia GETDATE () i przypisania wyniku do zmiennej oraz niewielka ilość czasu na ocenę DATEDIFF () i zwrócenie wyniku. Zaproponowane przeze mnie uproszczone podejście polegało na uzyskaniu przybliżonego pomiaru dla zapytań pojedynczych. Nie polecałbym stosowania tego podejścia w ścisłej pętli w procedurze składowanej. Gdybym miał serię zapytań w procedurze składowanej, mógłbym użyć tego podejścia, aby dodać dane wyjściowe debugowania w niektórych rozsądnych punktach, dodając kolumnę dyskryminatora, aby wiedzieć, która linia w procedurze wyemitowała wynik.
spencer7593

1
Zwykle trzymam się SET @t1 = GETDATE();u góry zapytania, a następnie SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();wklejam w rozsądnych punktach zapytania (odpowiednio edytując „UWAGA 1”). Traktowanie selekcji jako punktów przerwania, a nie pomiarów, jest semantycznie identyczne z twoim podejściem (chociaż ostateczny zestaw @ t1 jest fałszywy, a to zakłada, że ​​wszystkie zapytania powinny być mierzone). Jest to czysto mentalna optymalizacja / typowanie (jedna wklej na punkt przerwania, a nie dwie wklejki na zapytanie).
Brian

251

Jeśli chcesz dokładniejszego pomiaru niż powyższa odpowiedź:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

Wyniki będą w oknie Wiadomości .

Aktualizacja (2015-07-29):

Na popularne żądanie napisałem fragment kodu, którego można użyć do mierzenia czasu uruchomienia całej procedury składowanej, a nie jej składników. Chociaż zwraca to tylko czas potrzebny do ostatniego uruchomienia, istnieją dodatkowe statystyki zwrócone przez, sys.dm_exec_procedure_statsktóre również mogą mieć wartość:

-- 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
Zwróć uwagę, że ta funkcja nie jest dostępna, jeśli dostęp do bazy danych jest tylko do odczytu. 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
Czy istnieje sposób, w jaki mogę zobaczyć cały czas, który musi zostać wykonany przez procedurę składowaną? W tej chwili widzę wiele pojedynczych pomiarów.
Rookian

2
@Rookian, dodałem kod do odpowiedzi, aby ci w tym pomóc.
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]

Możesz również zobaczyć to rozwiązanie


9
To daje czas w nanosekundach. Milesekundy to DATEDIFF (MS, @ StartTime, @ EndTime)
d512

11

Innym sposobem jest użycie wbudowanej funkcji SQL Server o nazwie, Client Statisticsktóra jest dostępna poprzez Menu> Zapytanie> Uwzględnij statystyki klienta .

Możesz uruchomić każde zapytanie w oddzielnym oknie zapytania i porównać wyniki, które są podane w Client Statisticszakładce tuż obok Messageszakładki.

Na przykład na poniższym obrazku pokazuje, że średni czas, jaki upłynął, aby uzyskać odpowiedź serwera na jedno z moich zapytań, wynosi 39 milisekund.

Wynik

Możesz przeczytać wszystkie 3 sposoby uzyskiwania czasu wykonania tutaj . Może być nawet konieczne wyświetlenie w Estimated Execution Plan ctrlLcelu dalszego zbadania zapytania.


7

jeszcze lepiej, będzie to mierzyć średnią z n iteracji zapytania! Doskonały do ​​dokładniejszego czytania.

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
Zmieniłem MICROSECONDsię MILLISECONDi wyczyścić cache każdym razem po włożeniu między liniami begini declare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Działa jak urok i dokładnie to, czego szukałem. +1
Daniel Z.

1
Używam yr snippet do oceny przyrostowych poprawek wydajności procedury składowanej, bardzo zręcznie!
JayJay

Dziękuję wam obu. Sql robię już od dłuższego czasu, to dziwaczny język. Ale kiedy już wiesz, jakie są załamania i jak je obrócić na swoją korzyść, cóż, to bardzo pomaga XD
HumbleWebDev

3

Kliknij ikonę Statystyki, aby wyświetlić, a następnie uruchomić zapytanie, aby uzyskać czasy i dowiedzieć się, jak wydajne jest Twoje zapytanie

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.