2010-10-22 22 views
31

SQL 2005 profiler kullanarak bazı testler yapıyorum.Sorgu hızlı çalışıyor, ancak saklı yordamda yavaş çalışıyor

Sadece bir SQL sorgusu çalıştıran saklı yordamım var.

Kayıtlı yordamı çalıştırdığımda, uzun bir zaman alır ve 800.000 disk okuma gerçekleştirir.

Aynı sorguyu saklı yordamla çalıştırdığımda 14.000 disk okuması yapar.

Aynı sorguyu OPTION (recompile) ile çalıştırırsam 800.000 disk okuması gerektiğini buldum. Bundan

, ben saklı yordam her seferinde yeniden derlemeye ve bundan soruna neden olduğunu (muhtemelen hatalı) varsayımını.

Bu konuda biraz ışık tutabilir mi?

ARITHABORT ON ayarlı.

DECLARE 
@Contract_ID INT, 
@dt_From smalldatetime, 
@dt_To smalldatetime, 
@Last_Run_Date datetime, 
    @rv int 


SET @Contract_ID=38 
SET @dt_From='2010-09-01' 
SET @dt_To='2010-10-01' 
SET @Last_Run_Date='2010-10-08 10:59:59:070' 


-- This takes over fifteen seconds 
exec GET_IF_SETTLEMENT_ADJUSTMENT_REQUIRED @[email protected]_ID,@[email protected]_From,@[email protected]_To,@[email protected]_Run_Date 

-- This takes less than one second! 
SELECT @rv = (CASE WHEN EXISTS 
(
select * from 
view_contract_version_last_volume_update 
inner join contract_version 
on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id 
where [email protected]_ID 
and volume_date >= @dt_From 
and volume_date < @dt_To 
and last_write_date > @Last_Run_Date 
) 
THEN 1 else 0 end) 


-- With recompile option. Takes 15 seconds again! 
SELECT @rv = (CASE WHEN EXISTS 
(
select * from 
view_contract_version_last_volume_update 
inner join contract_version 
on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id 
where [email protected]_ID 
and volume_date >= @dt_From 
and volume_date < @dt_To 
and last_write_date > @Last_Run_Date 
) 
THEN 1 else 0 end) OPTION(recompile) 
+0

İki "Gerçek Sorgu Yürütme Planı" arasındaki fark nedir? – Andomar

cevap

61
: Burada
CREATE PROCEDURE [dbo].[GET_IF_SETTLEMENT_ADJUSTMENT_REQUIRED] 
@Contract_ID int, 
@dt_From smalldatetime, 
@dt_To smalldatetime, 
@Last_Run_Date datetime 
AS 
BEGIN 
DECLARE @rv int 


SELECT @rv = (CASE WHEN EXISTS 
(
    select * from 
    view_contract_version_last_volume_update 
    inner join contract_version 
    on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id 
    where [email protected]_ID 
    and volume_date >= @dt_From 
    and volume_date < @dt_To 
    and last_write_date > @Last_Run_Date 
) 
THEN 1 else 0 end) 

-- Note that we are RETURNING a value rather than SELECTING it. 
-- This means we can invoke this function from other stored procedures 
return @rv 
END 

bu sorunu göstermektedir koşuyorum bir komut dosyası: Burada

tüm saklı prosedürdür (Bu stackoverflow benzer bir sorun çözüldü, ama benimkini çözmedi)

Tamam, daha önce benzer sorunları yaşadık.

biz bu sabit şekilde, SP içindeki yerel parametreleri yaparak

DECLARE @LOCAL_Contract_ID int, 
     @LOCAL_dt_From smalldatetime, 
     @LOCAL_dt_To smalldatetime, 
     @LOCAL_Last_Run_Date datetime 

SELECT @LOCAL_Contract_ID = @Contract_ID, 
     @LOCAL_dt_From = @dt_From, 
     @LOCAL_dt_To = @dt_To, 
     @LOCAL_Last_Run_Date = @Last_Run_Date 

Sonra ziyade geçirildi parametrelere göre SP içindeki yerel parametreleri kullanmak gibi oldu.

Bu genellikle bizim için sorunu çözdü.

Biz bu koklama parametresine bağlı olduğuna inandığımız, ancak herhangi bir kanıt, üzgünüm ... X-) yok

DÜZENLEME:

bazı anlayışlı örnekler için Different Approaches to Correct SQL Server Parameter Sniffing göz at, açıklamalar ve düzeltmeler.

+3

Ve şimdi saklı yordam çok hızlı gidiyor profilerde 0 süresi vardır. Inanılmaz. Kargo Cult Programlama konusunda endişelenmeli miyim? Şu anda sadece çok sevindim, düzeltildi. :-) –

+0

Bu da sorunumu giderdi. O zamandan beri nasıl olduğundan emin değilsin. Sorgu 7 saniye koştu ve saklı yordam 7 dakika sürdü. Yerel Değişkenleri kullanarak 6 saniye içinde çalışır. Teşekkürler! – buzzzzjay

+0

2 günümü mağaza prosedürümün performansını arttırmak için yakıyorum, yürütme için 1 dak ve 20 saniye sürdü, ancak bir kez değiştirdikten sonra sadece 3 sn. Teşekkürler! :) – Hitusam

4

Bu özellikle datetime parametreleri ile, parametersniffing.

+0

+1 - bizim için oldu, biz [Adam Marshall] tarafından verilen cevabı takip ettik (http://stackoverflow.com/users/134653/adam -marshall) [SO: SQL Server: Sorgu hızlı, ancak prosedürden yavaş] (http://stackoverflow.com/questions/440944/sql-server-query-fast-but-slow-from-procedure) ve azaltılmış Bizim çalışma zamanımız ** 20 DAKİKA ** ila ** 4 SANİYE ** –

3

bir toplu ssms SQL parametre koklama ile ilgisi var bir SQL saklı yordam henüz anında çalıştırır içinde çalıştırmak için sonsuza kadar sürer neden konusunun neden olur sanırım.

Orada koklama parametresiyle ilgili birçok mükemmel makale var.

İşte bunlardan biri (ben yazmadım, sadece geçiyorum). Diğerleri de söylediğim gibi

http://www.sommarskog.se/query-plan-mysteries.html

3

, bu bir 'parametresi koklama' sorun olabilir.hat dahil deneyin:

OPTION (RECOMPILE) 

SQL sorgusu sonunda. http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

+0

+1 - bizim için oldu, biz cevabı takip ettim [Adam Marshall] (http://stackoverflow.com/users/134653/adam -marshall) [SO: SQL Server: Sorgu hızlı, ancak prosedürden yavaş] (http://stackoverflow.com/questions/440944/sql-server-query-fast-but-slow-from-procedure) ve azaltılmış bizim sp çalışma süresi ** 20 DAKİKA ** ila ** 4 SANAYİ ** –

1

ben de bugün aynı problem var:

ne parametre koklama açıklayan burada bir makale vardır. SP'yi bıraktım ve yeniden oluşturdum ve işe yaradı. Bu SP önbelleği ile bir şeydir ve SP'yi bıraktığınızda önbelleğe alınmış plan kaldırılmıştır. Aynı şeyi deneyebilir veya önbelleği silmek için 'DBCC FREEPROCCACHE' kullanabilirsiniz. Benim konuda

İlgili konular