Đo thời gian cần thiết để thực hiện truy vấn t-sql


156

Tôi có hai truy vấn t-sql bằng SqlServer 2005. Làm cách nào để đo thời gian cho mỗi lần chạy?

Sử dụng đồng hồ bấm giờ của tôi không cắt nó.


2
Bạn đang sử dụng Sql Server Management Studio? Nó thường hiển thị thời gian trôi qua cho mỗi truy vấn, mặc dù chỉ với độ phân giải thứ hai. Cũng xem câu hỏi liên quan này: stackoverflow.com/questions/8247587/ từ
mellamokb

Câu trả lời:


174

Một cách tiếp cận đơn giản để đo "thời gian trôi qua" giữa các sự kiện là chỉ lấy ngày và giờ hiện tại.

Trong SQL Server Management Studio

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

Để tính thời gian đã trôi qua, bạn có thể lấy các giá trị ngày đó thành các biến và sử dụng hàm 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;

Đó chỉ là một cách tiếp cận. Bạn cũng có thể nhận được thời gian trôi qua cho các truy vấn bằng SQL Profiler.


Tôi đã tìm tài liệu Sql Profiler về cách thực hiện việc này nhưng không thể tìm thấy tài liệu không cần đọc hàng giờ. Bạn có thể giới thiệu một liên kết "Profiler for Dummies" không?
TheMoot

@TheMoot Tôi biết tôi đến trễ nhưng các liên kết MSDN hoàn hảo cho nhu cầu "[Chủ đề] cho người giả" của bạn :). Hãy thử xem cái này Cách làm: Sử dụng SQL Profiler
John Odom

Có ai khác có vấn đề với việc sử dụng này trong studio quản lý sql? Tôi đã thêm nó vào một bộ khoảng 15 truy vấn trong một thủ tục được lưu trữ để thử nghiệm và nó mất quá nhiều thời gian để chạy. Tôi đã hủy sau 7 phút và tất cả các bộ tính giờ được thêm vào chỉ khoảng 2 phút. Vì vậy, tôi nghĩ rằng có một số vấn đề bộ đệm văn bản trả về hoặc có thể mất quá nhiều thời gian để tính toán tất cả các ngày tháng cho rất nhiều.
MH

2
@Hanoncs: Có một lượng nhỏ thời gian được sử dụng để đánh giá GETDATE () và gán kết quả cho một biến và một lượng nhỏ thời gian để đánh giá DATEDIFF () và trả về kết quả. Cách tiếp cận đơn giản mà tôi đề xuất là lấy số đo sơ bộ cho các truy vấn đơn lẻ. Tôi không khuyên bạn nên sử dụng phương pháp này trong một vòng lặp chặt chẽ trong một quy trình được lưu trữ. Nếu tôi có một loạt các truy vấn trong một thủ tục được lưu trữ, tôi có thể sử dụng phương pháp này để thêm một số đầu ra gỡ lỗi tại một số điểm hợp lý, thêm một cột phân biệt đối xử để tôi có thể biết dòng nào trong quy trình phát ra kết quả nào.
spencer7593

1
Tôi thường dán SET @t1 = GETDATE();ở đầu truy vấn của mình và sau đó dán SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();vào các điểm hợp lý trong truy vấn (chỉnh sửa "LƯU Ý 1" một cách thích hợp). Coi các lựa chọn là các điểm dừng thay vì các phép đo giống hệt nhau về mặt ngữ nghĩa với cách tiếp cận của bạn (mặc dù tập cuối cùng là @ t1 là giả mạo và điều này giả định rằng tất cả các truy vấn nên được đo). Đây hoàn toàn là một tối ưu hóa tinh thần / đánh máy (một lần dán cho mỗi điểm dừng, thay vì hai lần dán cho mỗi truy vấn).
Brian

251

Nếu bạn muốn một phép đo chính xác hơn câu trả lời ở trên:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

Kết quả sẽ có trong cửa sổ Tin nhắn .

Cập nhật (2015-07-29):

Theo yêu cầu phổ biến, tôi đã viết một đoạn mã mà bạn có thể sử dụng để tính toàn bộ thời gian chạy toàn bộ thủ tục được lưu trữ, thay vì các thành phần của nó. Mặc dù điều này chỉ trả về thời gian của lần chạy cuối cùng, nhưng có những số liệu thống kê bổ sung được trả về sys.dm_exec_procedure_statscũng có thể có giá trị:

-- 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
Chỉ cần lưu ý rằng chức năng này không khả dụng nếu quyền truy cập vào cơ sở dữ liệu của bạn là chỉ đọc. To use SET STATISTICS TIME, users must have the appropriate permissions to execute the Transact-SQL statement. The SHOWPLAN permission is not required. từ: technet.microsoft.com/en-us/l Library / ms190287.aspx
Rob

5
Có cách nào để tôi có thể thấy toàn bộ thời gian mà một thủ tục được lưu trữ cần phải thực thi không? Ngay bây giờ tôi thấy rất nhiều phép đo đơn lẻ.
Rookian

2
@Rookian, tôi đã thêm một số mã vào câu trả lời để giúp bạn điều đó.
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]

Bạn cũng có thể xem giải pháp này


9
Điều đó cho thời gian tính bằng nano giây. Một phần nghìn giây sẽ là DATEDIFF (MS, @ StartTime, @ EndTime)
d512

11

Một cách khác là sử dụng tính năng tích hợp SQL Server có tên Client Statisticscó thể truy cập thông qua Menu> Truy vấn> Bao gồm Thống kê Máy khách .

Bạn có thể chạy từng truy vấn trong cửa sổ truy vấn riêng biệt và so sánh các kết quả được đưa ra trong Client Statisticstab ngay bên cạnh Messagestab.

Ví dụ trong hình ảnh bên dưới cho thấy thời gian trung bình trôi qua để nhận được phản hồi của máy chủ cho một trong các truy vấn của tôi là 39 mili giây.

Kết quả

Bạn có thể đọc cả 3 cách để có được thời gian thực hiện tại đây . Bạn thậm chí có thể cần phải hiển thị Estimated Execution Plan ctrlLđể điều tra thêm về truy vấn của bạn.


7

thậm chí tốt hơn, điều này sẽ đo trung bình n lần lặp của truy vấn của bạn! Tuyệt vời cho một đọc chính xác hơ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
Tôi đã thay đổi MICROSECONDthành MILLISECONDvà để xóa bộ đệm mỗi lần tôi chèn các dòng sau giữa begindeclare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Hoạt động như sự quyến rũ và chính xác những gì tôi đang tìm kiếm. +1
Daniel Z.

1
Tôi đã sử dụng đoạn mã năm để đánh giá các chỉnh sửa hiệu suất gia tăng cho một thủ tục được lưu trữ, rất trơn tru!
JayJay

Cảm ơn cả hai người. Tôi đã làm sql từ lâu rồi, đó là một ngôn ngữ kỳ quặc. Nhưng một khi bạn biết các nút thắt là gì và làm thế nào để biến chúng thành lợi thế của bạn, thì nó cũng giúp ích rất nhiều cho XD
HumbleWebDev

3

Nhấp vào biểu tượng Thống kê để hiển thị và sau đó chạy truy vấn để nhận thời gian và để biết hiệu quả của truy vấn của bạn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.