2010-09-14 5 views
6

Mam kwerendę, która jest superszybka w SQL Server Management STudio i super slow po uruchomieniu pod sp_ExecuteSQL.SQL Server sp_ExecuteSQL i plany wykonawcze

Czy dzieje się tak z buforowaniem planów wykonawczych, które nie występują podczas uruchamiania pod spExecuteSQL?

+7

Zastanawiam się, kiedy „sp_executesql nie cache plany” mit nigdy nie umiera - czytaj [przekleństwa i błogosławieństwa dynamicznego SQL] (http://www.sommarskog.se/dynamic_sql.html) –

+0

@OMG Kucyki - czy sniffowanie parametrów może być problemem z sp_ExecuteSQL? – JNK

+0

@JNK: Odkąd przeżyłem to zachowanie, domyślnie włączyłem anty-paramiczne węszenie. –

Odpowiedz

8

nr

można zobaczyć zarówno planów wykonania i porównać je za pomocą następującego zapytania.

SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa 
where text like '%Some unique string in your query%' 
              and attribute='set_options' 

Wersja sp_executesql będzie miał objtype z "gotów"

+3

Dlaczego plany wykonania byłyby tak radykalnie różne? Na przykład, przyjrzałem się planowi wykonywania zapytań bezpośrednio z Sql Management Studio (trwa to 3 sekundy), a plan wykonania z sp_executeSql (trwa 5 lub więcej minut). plan z sp_executeSql całkowicie ignoruje kilka kluczowych indeksów znalezionych przez bezpośrednie połączenie. Czy ktoś może wyjaśnić, dlaczego połączenie ze studia zarządzania znajduje klucze, ale połączenie za pośrednictwem sp_ExecuteSql nie działa? –

+0

@NathanTregillus - Prawdopodobnie sniffowanie parametrów, możesz spojrzeć na buforowany plan XML, aby zobaczyć wartości parametrów, z którymi plan został faktycznie skompilowany. –

+0

dzięki za odpowiedź @MartinSmith. W rzeczywistości wynika to z tego, jak używamy contextInfo jako filtru w naszym widoku i jak nie jest on uwzględniany w planie wykonania –

1

Doświadczony takie samo zachowanie. (ustawiono opcje równe) Zwykły proces tworzenia równoległego planu i użycia sp_executesql wygenerował szeregowy plan.

declare @xyzParam1 datetime,@xyzParam2 datetime 
select @xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 
SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2 
; 

vs

exec sp_executesql N'SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2',N'@xyzParam1 datetime,@xyzParam2 datetime',@xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 

udało się uzyskać optymalny rezultat modyfikacji zużyty widok ponieważ zawiera np pozostawione sprzężenia dla danych, które zawsze były oczekiwane. (konwertowane na sprzężenie INNER)

Teraz zwykłe zapytanie wybiera ten sam plan, który uzyskano przy użyciu sp_executesql, a wydajność jest znacznie lepsza.