Bir t-sql sorgusunun yürütülmesi için geçen süreyi ölçme


156

SqlServer 2005 kullanarak iki t-sql sorgusu var. Her biri çalıştırmak için ne kadar sürer nasıl ölçebilirim?

Kronometremi kullanmak kesmiyor.


2
Sql Server Management Studio mu kullanıyorsunuz? Genellikle her bir sorgu için geçen süreyi, yalnızca ikinci çözünürlükle de olsa gösterir. Ayrıca bu ilgili soruya bakın: stackoverflow.com/questions/8247587/…
mellamokb

Yanıtlar:


174

Olaylar arasındaki "geçen zamanı" ölçmek için basit bir yaklaşım, sadece güncel tarih ve saati almaktır.

SQL Server Management Studio'da

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

Geçen süreleri hesaplamak için bu tarih değerlerini değişkenlere alabilir ve DATEDIFF işlevini kullanabilirsiniz:

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;

Bu sadece bir yaklaşım. SQL Profiler kullanarak sorgular için geçen süreleri de alabilirsiniz.


Bunu nasıl yapacağına dair Sql Profiler belgesini aradım, ancak saatlerce okuma gerektirmeyen dokümanı bulamadım. "Aptallar için Profiler" bağlantısı önerebilir misiniz?
TheMoot

@TheMoot Geç kaldığımı biliyorum ama MSDN bağlantıları "[Konu] Aptallar" ihtiyaçları için mükemmel :). Şuna bir göz atmaya çalışın Nasıl Yapılır: SQL Profiler'ı Kullanma
John Odom

Bunu sql yönetim stüdyosunda kullanmakla ilgili başka kimse oldu mu? Test için saklı bir yordamda yaklaşık 15 sorgu kümesine ekledim ve çalışması çok uzun sürüyor. 7 Dakikada iptal ve eklenen tüm zamanlayıcılar sadece yaklaşık 2 dakika oldu. Bu yüzden bazı dönüş metin önbellek sorunu olduğunu düşünüyorum ya da belki çok için tüm dateiffs hesaplamak çok uzun sürer.
MH

2
@Hanoncs: GETDATE () öğesini değerlendirmek ve sonucu bir değişkene atamak için az bir süre ve DATEDIFF () öğesini değerlendirmek ve sonucu döndürmek için az bir süre vardır. Önerdiğim basit yaklaşım singleton sorguları için kabaca bir ölçüm yapmaktı. Saklı bir yordamda sıkı bir döngü içinde bu yaklaşımı kullanmanızı tavsiye etmem. Saklı bir yordamda bir dizi sorgu varsa, bu yaklaşım bazı makul noktalarda bazı hata ayıklama çıktı eklemek için, bir ayrımcı sütun ekleyerek yordamda hangi satırın hangi sonuç yayınladı bilmek için kullanabilirsiniz.
spencer7593

1
Ben genellikle SET @t1 = GETDATE();benim sorgu üstünde sopa ve sonra SET @t2 = GETDATE();SELECT 'NOTE 1',DATEDIFF(millisecond,@t1,@t2) AS elapsed_ms;SET @t1 = GETDATE();sorgu içinde ("Not 1" uygun şekilde düzenlenmesi) makul noktalara yapıştırın . Seçimleri ölçümler yerine kesme noktaları olarak ele almak, yaklaşımınızla anlamsal olarak aynıdır (@ t1 olarak ayarlanan son değer sahte olsa da bu, tüm sorguların ölçülmesi gerektiğini varsayar). Bu tamamen bir zihinsel / yazım optimizasyonudur (sorgu başına iki macun yerine kesme noktası başına bir macun).
Brian

251

Yukarıdaki yanıttan daha doğru bir ölçüm istiyorsanız:

set statistics time on 

-- Query 1 goes here

-- Query 2 goes here

set statistics time off

Sonuçlar Mesajlar penceresinde olacaktır.

Güncelleme (2015-07-29):

Popüler istek üzerine, bileşenleri yerine tüm saklı yordam çalıştırmayı zamanlamak için kullanabileceğiniz bir kod snippet'i yazdım. Bu yalnızca son çalıştırma tarafından harcanan süreyi döndürse sys.dm_exec_procedure_statsde, bu değerin döndürdüğü ek istatistikler de vardır:

-- 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
Veritabanına erişiminiz salt okunursa bu işlevin kullanılamayacağını unutmayın. 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/tr-tr/library/ms190287.aspx
Rob

5
Saklı yordamın yürütülmesi gereken tüm zamanı görebildiğim bir yol var mı? Şu anda birçok tek ölçüm görüyorum.
Rookian

2
@Rookian, bu konuda size yardımcı olması için cevaba bazı kodlar ekledim.
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]

Ayrıca bu çözümü de görebilirsiniz


9
Bu, nanosaniye cinsinden zaman verir. Milisaniye DATEDIFF (MS, @ StartTime, @
EndTime

11

Başka bir yol, Menü> Sorgu> İstemci İstatistiklerini İçerClient Statistics yoluyla erişilebilen bir SQL Server yerleşik özelliğini kullanmaktır .

Her bir sorguyu ayrılmış sorgu penceresinde çalıştırabilir ve Client Statisticssekmede verilen sonuçlarıMessages .

Örneğin aşağıdaki resimde, sorgularımdan biri için sunucu yanıtını almak için geçen ortalama sürenin 39 milisaniye olduğunu gösterir.

Sonuç

İçeri yürütme zamanı elde etmek için tüm 3 yolu okuyabilir burada . Estimated Execution Plan ctrlLSorgunuz hakkında daha ayrıntılı inceleme için görüntülemeniz bile gerekebilir .


7

daha da iyisi, bu, sorgunuzun n yinelemelerinin ortalamasını ölçer! Daha doğru bir okuma için harika.

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
Değiştim MICROSECONDiçin MILLISECONDve ben arasındaki çizgileri takip sokulan önbellek her şey temizlemek için beginve declare @t0 ...: CHECKPOINT; DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE;. Cazibe ve tam olarak aradığım şey gibi çalışır. +1
Daniel Z.

1
Saklı bir yordam için artan performans tweaks ölçmek için yr snippet'i kullanıyorum, çok kaygan!
JayJay

İkinize de teşekkürler. Ben uzun zamandır sql yapıyorum, bu ilginç bir dil. Ama karışıklıkların ne olduğunu ve bunları avantajınıza nasıl döndüreceğinizi
öğrendikten sonra

3

Görüntülemek için İstatistikler simgesini tıklayın ve ardından zamanlamaları almak ve sorgunuzun ne kadar verimli olduğunu öğrenmek için sorguyu çalıştırın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.