Измерьте время, необходимое для выполнения запроса t-sql

156

У меня есть два запроса t-sql, использующих SqlServer 2005. Как я могу измерить, сколько времени занимает выполнение каждого из них?

Использование моего секундомера не сокращает это.

TheMoot
источник
2
Вы используете Sql Server Management Studio? Как правило, он отображает время, прошедшее для каждого запроса, хотя только со вторым разрешением. Также см. Этот связанный вопрос: stackoverflow.com/questions/8247587/…
mellamokb

Ответы:

174

Один из упрощенных подходов к измерению «прошедшего времени» между событиями - просто получить текущую дату и время.

В SQL Server Management Studio

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

Чтобы вычислить истекшее время, вы можете захватить эти значения даты в переменные и использовать функцию 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;

Это только один подход. Вы также можете получить истекшее время для запросов, используя SQL Profiler.

spencer7593
источник
Я искал документ Sql Profiler о том, как это сделать, но не смог найти документ, который не требовал многочасового чтения. Можете ли вы порекомендовать ссылку «Профилировщик для чайников»?
TheMoot
@TheMoot Я знаю, что опаздываю, но ссылки MSDN идеально подходят для ваших потребностей "[Тема] для чайников" :). Попробуйте взглянуть на это Как: использовать SQL Profiler
Джон Одом
У кого-нибудь еще были проблемы с использованием этого в студии управления sql? Я добавил его в набор из примерно 15 запросов в хранимой процедуре для тестирования, и это занимает слишком много времени для запуска. Я отменил в 7 минут, и все таймеры были добавлены только около 2 минут. Так что я думаю, что есть некоторая проблема с кешем возвращаемого текста или, может быть, слишком много времени для вычисления всех датировок для такого количества.
MH
2
@Hanoncs: для оценки GETDATE () и присвоения результата переменной используется небольшое количество времени, а для вычисления DATEDIFF () и возврата результата - небольшое количество времени. Упрощенный подход, который я предложил, состоял в том, чтобы получить приблизительное измерение для одноэлементных запросов. Я бы не рекомендовал использовать этот подход в узком цикле хранимой процедуры. Если бы у меня была последовательность запросов в хранимой процедуре, я мог бы использовать этот подход для добавления некоторых результатов отладки в некоторые разумные моменты, добавив столбец дискриминатора, чтобы я мог знать, какая строка в процедуре выдает какой результат.
spencer7593
1
Я обычно придерживаюсь SET @t1 = GETDATE();верхней части моего запроса и затем вставляю в SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();разумные моменты в запросе (редактируя "ПРИМЕЧАНИЕ 1" соответственно). Обработка выборок как точек останова, а не измерений семантически идентична вашему подходу (хотя конечный набор @ t1 является ложным, и это предполагает, что все запросы должны быть измерены). Это чисто ментальная / типизированная оптимизация (одна вставка на точку останова, а не две вставки на запрос).
Брайан
251

Если вы хотите более точное измерение, чем ответ выше:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

Результаты будут в окне сообщений .

Обновление (2015-07-29):

По популярному запросу я написал фрагмент кода, который можно использовать для определения времени выполнения всей хранимой процедуры, а не ее компонентов. Хотя это только возвращает время, затраченное на последний запуск, есть дополнительные статистические данные, sys.dm_exec_procedure_statsкоторые также могут иметь значение:

-- 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
Просто обратите внимание, что эта функция недоступна, если ваш доступ к базе данных только для чтения. To use SET STATISTICS TIME, users must have the appropriate permissions to execute the Transact-SQL statement. The SHOWPLAN permission is not required. От: technet.microsoft.com/en-us/library/ms190287.aspx
Роб
5
Есть ли способ, где я могу видеть все время, что хранимая процедура должна выполнить? Прямо сейчас я вижу много отдельных измерений.
Новобранец
2
@Rookian, я добавил код к ответу, чтобы помочь тебе в этом.
Михаил Гольдштейн
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]

Вы также можете увидеть это решение

Атик Саркер
источник
9
Это дает время в наносекундах. Миллисекунды будут DATEDIFF (MS, @ StartTime, @ EndTime)
d512,
11

Другой способ - использовать встроенную функцию SQL Server с именем, Client Statisticsкоторая доступна через Меню> Запрос> Включить статистику клиента .

Вы можете выполнить каждый запрос в отдельном окне запроса и сравнить результаты, которые приведены на Client Statisticsвкладке рядом с Messagesвкладкой.

Например, на рисунке ниже показано, что среднее время, затраченное на получение ответа сервера на один из моих запросов, составляет 39 миллисекунд.

результат

Вы можете прочитать все 3 способа получения времени выполнения здесь . Возможно, вам даже понадобится отобразить Estimated Execution Plan ctrlLдля дальнейшего изучения вашего запроса.

Мухаммед Мусави
источник
7

еще лучше, это будет измерять среднее из n итераций вашего запроса! Отлично подходит для более точного чтения.

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
источник
4
Я изменил MICROSECONDк MILLISECONDи очистить кэш каждый раз я вставленный следующие строки между beginи declare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Работает как шарм и именно то, что я искал. +1
Даниэль З.
1
Я использую ваш фрагмент кода для оценки дополнительных настроек производительности хранимой процедуры, очень гладко!
JayJay
Спасибо вам обоим. Я давно занимаюсь sql, это странный язык. Но как только вы поймете, что такое изломы и как их раскрутить в свою пользу, это очень помогает. XD
HumbleWebDev
3

Нажмите на иконку Статистика, чтобы отобразить, а затем выполните запрос, чтобы узнать сроки и узнать, насколько эффективен ваш запрос.

Ашиш Патель
источник