测量执行t-sql查询所需的时间


Answers:


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获取查询的经过时间。


我寻找了有关如何执行此操作的Sql Profiler文档,但找不到不需要花大量时间阅读的文档。您可以推荐“傻瓜探查器”链接吗?
TheMoot 2012年

@TheMoot我知道我来晚了,但是MSDN链接非常适合您的“ [傻瓜主题]”需求:)。尝试看一下如何:使用SQL事件探查器
John Odom

还有其他人在sql management studio中使用它时遇到问题吗?我将它添加到存储过程中约15个查询中,以进行测试,并且运行时间太长。我在7分钟取消,所有计时器合计只有2分钟左右。因此,我认为存在一些返回文本缓存问题,或者可能需要很长时间才能计算出这么多的所有datediff。
MH

2
@Hanoncs:有少量时间用于评估GETDATE()并将结果分配给变量,也有少量时间用于评估DATEDIFF()并返回结果。我提出的简单方法是对单例查询进行粗略的度量。我不建议在存储过程的紧密循环中使用这种方法。如果我在存储过程中有一系列查询,则可以使用这种方法在一些明智的点添加一些调试输出,并添加一个鉴别符列,这样我就可以知道过程中的哪一行发出了哪个结果。
spencer7593 '17

1
我通常会停留SET @t1 = GETDATE();在查询的顶部,然后粘贴SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();到查询中的适当位置(适当地编辑“注意1”)。从语义上讲,将选择作为断点而不是度量值与您的方法相同(尽管@ t1的最终集合是虚假的,并且假定应该对所有查询进行度量)。这纯粹是一种心理/类型优化(每个断点一个粘贴,而不是每个查询两个粘贴)。
布莱恩(Brian)

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/zh-cn/library/ms190287.aspx
Rob

5
有没有一种方法可以让我看到存储过程需要执行的全部时间?现在,我看到很多单个测量值。
Rookian

2
@Rookian,我在答案中添加了一些代码来帮助您。
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]

您也可以看到此解决方案


9
那给出的时间以纳秒为单位。毫秒为DATEDIFF(MS,@ StartTime,@ EndTime)
d512 2015年

11

另一种方法是使用名为SQL Server的内置功能Client Statistics,可以通过菜单>查询>包括客户端统计信息对其进行访问

您可以在单独的查询窗口中运行每个查询,并比较Client Statistics标签旁边的Messages标签中给出的结果。

例如,在下面的图像中,它显示了获取我的一个查询的服务器回复所花费的平均时间为39毫秒。

结果

您可以在此处阅读所有三种获取执行时间的方法。您甚至可能需要显示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

4
我改变了MICROSECONDMILLISECOND并清除我插入以下行之间的缓存每次begindeclare @t0 ...CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;。像魅力一样工作,而且正是我想要的。+1
Daniel Z.

1
我一直在使用yr片段来评估存储过程的增量性能调整,非常流畅!
JayJay

谢谢你们俩。我已经使用SQL很久了,它是一种古怪的语言。但是一旦您知道了什么是纠结以及如何利用它们来发挥自己的优势,那么它对XD
很有帮助-HumbleWebDev

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.