Przeanalizujmy te dwa stwierdzenia:
IF (CONDITION 1) OR (CONDITION 2)
...
IF (CONDITION 3) AND (CONDITION 4)
...
Jeśli CONDITION 1
tak TRUE
, zostanie CONDITION 2
sprawdzone?
Jeśli CONDITION 3
tak FALSE
, zostanie CONDITION 4
sprawdzone?
Co z warunkami na WHERE
: czy silnik SQL Server optymalizuje wszystkie warunki w WHERE
klauzuli? Czy programiści powinni umieszczać warunki we właściwej kolejności, aby mieć pewność, że optymalizator SQL Server rozwiąże je we właściwy sposób?
DODANY:
Dziękuję Jackowi za link, niespodzianka z kodu t-sql:
IF 1/0 = 1 OR 1 = 1
SELECT 'True' AS result
ELSE
SELECT 'False' AS result
IF 1/0 = 1 AND 1 = 0
SELECT 'True' AS result
ELSE
SELECT 'False' AS result
W tym przypadku nie występuje wyjątek dzielenia przez zero .
WNIOSEK:
Jeśli w C ++ / C # / VB występuje zwarcie, dlaczego SQL Server go nie ma?
Aby naprawdę na to odpowiedzieć, rzućmy okiem na to, jak oboje pracują w warunkach. Wszystkie C ++ / C # / VB mają zwarcie zdefiniowane w specyfikacjach języka, aby przyspieszyć wykonanie kodu. Po co zawracać sobie głowę oceną N warunków, gdy pierwszy jest już prawdziwy, lub M AND warunków, gdy pierwszy jest już fałszywy.
Jako programiści musimy pamiętać, że SQL Server działa inaczej. Jest to system oparty na kosztach. Aby uzyskać optymalny plan wykonania dla naszego zapytania, procesor zapytań musi ocenić każdy warunek i przypisać mu koszt. Koszty te są następnie oceniane jako całość, aby utworzyć próg, który musi być niższy niż zdefiniowany próg, który SQL Server ma dla dobrego planu. Jeśli koszt jest niższy niż zdefiniowany próg, stosowany jest plan, jeśli nie, cały proces powtarza się ponownie z inną kombinacją kosztów warunkowych. Koszt tutaj to albo skanowanie, albo wyszukiwanie, łączenie scalające, łączenie mieszające itp. Z tego powodu zwarcie, jak to jest dostępne w C ++ / C # / VB, po prostu nie jest możliwe. Możesz pomyśleć, że wymuszenie użycia indeksu na kolumnie liczy się jako zwarcie, ale tak nie jest. Wymusza to jedynie użycie tego indeksu, a tym samym skraca listę możliwych planów wykonania. System nadal opiera się na kosztach.
Jako programista musisz mieć świadomość, że SQL Server nie powoduje zwarć, jak ma to miejsce w innych językach programowania i nie możesz nic zrobić, aby zmusić go do tego.
Odpowiedzi:
W SQL Server nie ma gwarancji, czy lub w jakiej kolejności instrukcje będą przetwarzane w
WHERE
klauzuli. Pojedyncze wyrażenie, które pozwala na zwarcie instrukcji, toCASE
-WHEN
. Poniżej znajduje się odpowiedź, którą opublikowałem na Stackoverflow:Jak SQL Server zwiera GDZIE ocena stanu
Aby uzyskać więcej informacji, sprawdź pierwszy link w powyższym wpisie na blogu, który prowadzi do innego bloga:
Czy w SQL Server występuje zwarcie?
źródło
case
nie jest bezpiecznyCASE
przerwy: dba.stackexchange.com/questions/12941/…W języku T-SQL
IF
instrukcja może powodować zwarcie, ale nie można na niej polegać, oceniając wyrażenia w kolejnościźródło
SQL jest deklaratywnym językiem programowania. W przeciwieństwie do powiedzmy C ++, który jest imperatywnym językiem programowania.
Oznacza to, że możesz powiedzieć, co chcesz w wyniku końcowym, ale nie możesz dyktować, w jaki sposób wynik jest wykonywany, wszystko zależy od silnika.
Jedynym prawdziwym sposobem zagwarantowania „zwarcia” (lub dowolnego innego przepływu sterowania ) w środku
WHERE
jest użycie widoków indeksowanych, tabel tymczasowych i podobnych mechanizmów.PS. Możesz także użyć wskazówek dotyczących planu wykonania (aby „podpowiedzieć” silnikowi, jak wykonać zapytanie, które indeksy użyć i JAK ich używać), pomyślałem, że powinienem o tym wspomnieć, skoro jesteśmy na ten temat ...
źródło
1) - LUB (jeden lub oba warunki będą PRAWDA)
jeśli warunek 1 ma wartość PRAWDA, wówczas warunek 2 również sprawdzi, czy może to być PRAWDA lub FAŁSZ
--AND (oba warunki muszą być PRAWDĄ)
jeśli warunek 1 ma wartość FAŁSZ, warunek 2 nie zostanie sprawdzony
źródło
WHERE
klauzulach.Jedynym sposobem kontrolowania, w jaki sposób warunki w klauzuli WHERE, jest użycie nawiasów, aby je zgrupować.
jest bardzo różny od
źródło
AND
ma wyższy priorytet niżOR
. Oba są równoważne. To, co powiesz, będzie prawdziwe dlaWHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = x
zapytania. Zobacz test Fiddle SQL