2016-02-25 30 views
5

Czy jest jakaś różnica pod względem wydajności, gdy wiele zapytań jest uruchamianych z (różnymi) stałymi wartościami w klauzuli where, w przeciwieństwie do zapytania z zadeklarowanymi parametrami u góry, gdzie zamiast tego zmienia się wartość parametru?SQL - jakakolwiek różnica w wydajności przy użyciu wartości stałych vs parametrów?

zapytania z próbki ze stałą wartością w którym klauzula:

select 
* 
from [table] 
where [guid_field] = '00000000-0000-0000-000000000000' --value changes 

Proponowany (lepsza?) Kwerenda z deklarowanymi parametrami:

declare @var uniqueidentifier = '00000000-0000-0000-000000000000' --value changes 

select 
* 
from [table] 
where [guid_field] = @var 

Czy jest jakaś różnica? Patrzę na plany wykonania czegoś podobnego do dwóch powyższych zapytań i nie widzę żadnej różnicy. Jednak wydaje mi się pamiętać, że jeśli użyjesz wartości stałych w instrukcjach SQL, to SQL Server nie użyje ponownie tych samych planów wykonywania zapytań, czy coś takiego, które spowoduje gorszą wydajność - ale czy to prawda?

+0

Zasady sporządzania i stashing zapytań SQL Server są dość skomplikowane. Ogólnie rzecz biorąc, myślę, że kompiluje zapytanie oparte na pierwszych przekazanych parametrach. Tak więc, jeśli plan zapytania jest buforowany i zmieniasz parametry, wtedy kolejne użycie planu może nie być optymalne dla nowych wartości. Jednak powinno być w porządku dla pierwszego wywołania, które generuje plan zapytania. Uwaga: począwszy od pustej tabeli, a następnie wypełnienie tabeli może również wpłynąć na najlepszy plan, nawet przy przekazywaniu tej samej wartości. –

Odpowiedz

1

Ważne jest, aby tutaj rozróżnić parametry i zmienne. Parametry przekazywane są do procedur i funkcji, deklarowane są zmienne.

Adresowanie zmiennych, które jest tym, co SQL w pytaniu, podczas kompilowania pakietu ad-hoc, SQL Server kompiluje każdą instrukcję na swoim. Tak więc podczas kompilowania zapytania ze zmienną nie wraca ono do sprawdzenia żadnego przypisania, więc skompiluje plan wykonania zoptymalizowany dla nieznanej zmiennej. Po pierwszym uruchomieniu ten plan wykonania zostanie dodany do pamięci podręcznej planu, a następnie przyszłe wykonanie może i ponownie będzie używać tej pamięci podręcznej dla wszystkich wartości zmiennych.

Po przekazaniu stałej zapytanie jest kompilowane na podstawie tej konkretnej wartości, dzięki czemu można utworzyć bardziej optymalny plan, ale z dodatkowym kosztem ponownej kompilacji.

Więc konkretnie odpowiedzieć na pytanie:

Jednak wydaje mi się, aby przypomnieć, że jeśli używasz wartości stałych w instrukcji SQL Serwer SQL nie będzie ponownego wykorzystania tych samych planów wykonania zapytań, lub coś w tym względzie to powoduje gorszą wydajność - ale czy to prawda?

Tak, prawdą jest, że ten sam plan nie może być ponownie użyty dla różnych wartości stałych, ale niekoniecznie powoduje gorszą wydajność. Możliwe, że dla tej konkretnej stałej można zastosować bardziej odpowiedni plan (np. Wybierając wyszukiwanie zakładek w skanie indeksu dla danych rzadkich), a zmiana planu kwerendy może przeważyć koszt ponownej kompilacji. Tak jak prawie zawsze w przypadku pytań dotyczących wydajności SQL. Odpowiedź brzmi: to zależy od.

W przypadku parametrów domyślne zachowanie polega na tym, że plan wykonania jest kompilowany na podstawie tego, kiedy parametr (y) użyty, gdy procedura lub funkcja jest wykonywana po raz pierwszy.

I odpowiedziałeś podobne pytania przed bardziej szczegółowo z przykładów, które obejmują wiele wyżej, więc zamiast powtarzania różnych aspektów nim będę po prostu połączyć pytania:

0

pierwsze, trzeba pamiętać, że zmienna lokalna nie jest taki sam jak parametr.

Zakładając, że kolumna jest indeksowana lub ma statystyki, SQL Server używa histogramu statystycznego do zebrania szacunkowej liczby wierszy kwalifikacyjnych w oparciu o dostarczoną wartość stałą. Zapytanie będzie również automatycznie sparametryzowane i zapisane w pamięci podręcznej, jeśli jest trywialne (daje taki sam plan niezależnie od wartości), aby kolejne egzekucje pozwoliły uniknąć kosztów kompilacji zapytań.

Kwerenda sparametryzowana generuje również plan z wykorzystaniem histogramu statystyk z początkowo dostarczoną wartością parametru. Plan jest buforowany i ponownie wykorzystywany do kolejnych egzekucji, niezależnie od tego, czy jest to trywialne, czy nie.

W przypadku zmiennej lokalnej SQL Server używa ogólnej statystyki do wygenerowania planu, ponieważ faktyczna wartość jest nieznana podczas kompilacji. Ten plan może być dobry dla niektórych wartości, ale nieoptymalny dla innych, gdy zapytanie nie jest trywialne.

1

Jest tak wiele rzeczy, zaangażowanych w swoje pytanie, a wszystko ma do czynienia ze statystyką ..

SQL kompiluje plan wykonania nawet dla zapytań ad hoc i przechowuje je w pamięci podręcznej planu do ponownego użycia, jeśli są one uważane za bezpieczne.

select * into test from sys.objects 

select schema_id,count(*) from test 
group by schema_id 


--schema_id 1 has 15 
--4 has 44 rows 

pierwsze pytanie: staramy inny dosłownego za każdym razem, więc SQL zapisuje plan jeśli uzna za safe..You widzi drugie szacunki zapytań są takie same jak literla 4, ponieważ SQL zapisane plan 4

--lets clear cache first--not for prod 
dbcc freeproccache 

select * from test 
where schema_id=4 

wyjściowego:

enter image description here

select * from test where 
schema_id=1 

wyjściowa:

enter image description here

sekund zapytać:
Przekazywanie zmiennej lokalnej jako param, pozwala wykorzystywać tę samą wartość 4

--lets pass 4 which we know has 44 rows,estimates are 44 whem we used literals 
declare @id int 
set @id=4 
select * from test 

Jak widać poniżej zrzucie , używając zmiennych lokalnych oszacowanych z mniejszą ilością 29,5 wiersza, co ma związek ze statystyką s ..

wyjściowa:

enter image description here

Tak w skrócie, statystyki są kluczowe przy wyborze planu kwerend (zagnieżdżone pętle, czyli skanowanie lub szukać) z przykładów, można zobaczyć, jak szacunki są różne dla każdej metody.Ponadto z perspektywy rozrzutu pamięci podręcznej planu

Możesz także zastanawiać się, co się stanie, jeśli przejdę przez wiele zapytań ad hoc, ponieważ SQL generuje nowy plan dla tego samego zapytania, nawet jeśli jest zmiana w przestrzeni, poniżej linki które pomogą Ci

podobne odczyty:
http://www.sqlskills.com/blogs/kimberly/plan-cache-adhoc-workloads-and-clearing-the-single-use-plan-cache-bloat/
http://sqlperformance.com/2012/11/t-sql-queries/ten-common-threats-to-execution-plan-quality

Powiązane problemy