Napotkałem dziwną sytuację, gdy dołączałem OPTION (RECOMPILE)
do mojego zapytania powoduje, że działa ono w pół sekundy, podczas gdy jego pominięcie powoduje, że zapytanie trwa znacznie ponad pięć minut.
Dzieje się tak, gdy zapytanie jest wykonywane z programu Query Analyzer lub z mojego programu C # za pośrednictwem SqlCommand.ExecuteReader()
. Dzwonienie (lub nie dzwonienie) DBCC FREEPROCCACHE
lub DBCC dropcleanbuffers
nie ma znaczenia; Wyniki zapytania są zawsze zwracane natychmiastowo OPTION (RECOMPILE)
i dłużej niż pięć minut bez niego. Zapytanie jest zawsze wywoływane z tymi samymi parametrami [na potrzeby tego testu].
Używam SQL Server 2008.
Jestem dość komfortowy w pisaniu SQL, ale nigdy wcześniej nie użyłem OPTION
polecenia w zapytaniu i nie byłem zaznajomiony z całą koncepcją pamięci podręcznych planu do czasu skanowania postów na tym forum. Z postów rozumiem, że OPTION (RECOMPILE)
jest to kosztowna operacja. Najwyraźniej tworzy nową strategię wyszukiwania dla zapytania. Dlaczego więc tak się dzieje, że kolejne zapytania pomijają rozszerzenieOPTION (RECOMPILE)
są tak wolne? Czy kolejne zapytania nie powinny wykorzystywać strategii wyszukiwania, która została obliczona podczas poprzedniego wywołania, które zawierało wskazówkę dotyczącą ponownej kompilacji?
Czy zapytanie wymagające rekompilacji przy każdym wywołaniu jest bardzo niezwykłe?
Przepraszam za pytanie dla początkujących, ale naprawdę nie mogę się z tym pogodzić.
AKTUALIZACJA: Poproszono mnie o wysłanie zapytania ...
select acctNo,min(date) earliestDate
from(
select acctNo,tradeDate as date
from datafeed_trans
where feedid=@feedID and feedDate=@feedDate
union
select acctNo,feedDate as date
from datafeed_money
where feedid=@feedID and feedDate=@feedDate
union
select acctNo,feedDate as date
from datafeed_jnl
where feedid=@feedID and feedDate=@feedDate
)t1
group by t1.acctNo
OPTION(RECOMPILE)
Uruchamiając test z Query Analyzer, poprzedzam następujące wiersze:
declare @feedID int
select @feedID=20
declare @feedDate datetime
select @feedDate='1/2/2009'
Podczas wywoływania go z mojego programu C # parametry są przekazywane za pośrednictwem SqlCommand.Parameters
właściwości.
Na potrzeby tej dyskusji można założyć, że parametry nigdy się nie zmieniają, więc możemy wykluczyć nieoptymalny parametr pachnący jako przyczynę.
X = @X OR @X IS NULL
się X=@X
i wykonywanie wyszukiwania Zobacz tutaj lub przesuwanie predykatów dalej w dół w stosunku do widoku z funkcjami okna
RECOMPILE
. W każdym przypadku zapisz plany wykonania i przyjrzyj się różnicom.