Pytanie LUB Zwarcie operatora w SQL Server


Chcę skonsultować się z SQL Server LUB zwarciem

Kod:

   DECLARE @tempTable table
      (
         id int
      )
      INSERT @tempTable(id) values(1)

      DECLARE @id varchar(10)
      SET @id = 'x'
      SELECT * FROM @tempTable WHERE 1=1 OR id = @id --successfully
      SELECT * FROM @tempTable WHERE @id = 'x' OR id = @id --Exception not Convert 'x' to int

Czemu? 1 = 1 i @ id = "x" jest prawdziwe.

Serwer SQL Operator OR: czy funkcja zwarcia?

DZIĘKI


16
2018-06-27 05:13


pochodzenie


Jest bez gwarancji w jaki sposób i które części OR warunek jest oceniany jako pierwszy (lub w ogóle). T-SQL jest NIE jak C # w ten sposób. ty nie może polegać na zwarciu binarnym. - marc_s
Why? 1=1 and @id='x' is true - to jest lub właściwie to nie i. - juergen d
Tutaj, w tym INSERT @tempTable (id) wartości (1), brakuje INTO. - vijay
LUB zwarte jest moje wątpliwości, ale moje biuro sql kodowania jest ((@ id ma wartość NULL lub id = id) AND (@name is NULL OR name = @ name)), więc chciałbym wiedzieć, czy zwarcie Ponieważ Ta decyzja efektywność procesu Aby to zrobić, wystarczy ponownie wykorzystać plan zapytania - NotTwoWayStreet


Odpowiedzi:


Wewnątrz SQL, tam nie jest wymogiem że klauzula OR zrywa się wcześnie. Innymi słowy, do optymalizatora należy sprawdzenie, czy oba warunki zostały wykonane jednocześnie. Nie jestem ekspertem od optymalizatora MSSQL, ale widziałem przypadki, w których optymalizator ma i nie zwarł klauzuli OR.


14
2018-06-27 05:20



LUB zwarte jest moje wątpliwości, ale moje biuro sql kodowania jest ((@ id ma wartość NULL lub id = id) AND (@name is NULL OR name = @ name)), więc chciałbym wiedzieć, czy zwarcie Ponieważ Ta decyzja efektywność procesu Aby to zrobić, wystarczy ponownie wykorzystać plan zapytania - NotTwoWayStreet


Natknąłem się na to pytanie i już znalazłem ten wpis na blogu: http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/

Serwer SQL może dowolnie optymalizować zapytanie w dowolnym miejscu, więc w przykładzie podanym w poście na blogu nie można polegać na zwarciu.

Jednak CASE jest najwyraźniej udokumentowane w celu oceny w pisemnej kolejności - sprawdź komentarze tego wpisu na blogu.


5
2017-08-14 19:35





Jest oczywiste, że serwer MS Sql obsługuje teorię zwarć, aby poprawić wydajność, unikając niepotrzebnego sprawdzania,

Wspieranie Przykład:

SELECT 'TEST'
WHERE 1 = 'A'

SELECT 'TEST'
WHERE 1 = 1 OR 1 = 'A'

W tym przypadku pierwszy przykład spowodowałby błąd "Konwersja nie powiodła się podczas przekształcania wartości varcharnej" A "na typ danych int."

Podczas gdy drugi działa z łatwością, gdy warunek 1 = 1 jest oceniany jako TRUE, a zatem drugi warunek nie działa wcale.

Ponadto

SELECT 'TEST'
WHERE 1 = 0 OR 1 = 'A'

tutaj pierwszy warunek zostanie oceniony jako fałszywy, a zatem DBMS pójdzie na drugi warunek i ponownie dostaniesz błąd konwersji, jak w powyższym przykładzie.

UWAGA: ZGADZAM SIĘ Z BŁĘDNYM WARUNKIEM, ABY ZREALIZOWAĆ POGODĘ WARUNEK JEST WYKONANY LUB SKRÓCONY JEŚLI QUERY WYNIKI BŁĘDU ZNALAZŁO WYKONANO WARUNEK, ZWIĘKSZONO INACZEJ.

PROSTE WYJAŚNIENIE

Rozważać,

WHERE 1 = 1 OR 2 = 2

ponieważ pierwszy warunek jest oceniany PRAWDZIWE, bez znaczenia dla oceny drugiego warunku, ponieważ jego ocena ma dowolną wartość w ogóle nie wpłynęłoby to na wynik, więc jego dobra okazja dla serwera SQL, aby zaoszczędzić czas wykonania kwerendy, pomijając niepotrzebne sprawdzanie stanu lub ocenę.

w przypadku "LUB" jeśli oceniany jest pierwszy warunek PRAWDZIWE cały łańcuch połączony przez "LUB" zostanie uznany za prawdziwy, bez oceny innych.

condition1 OR condition2 OR ..... OR conditionN

jeśli warunek1 zostanie oceniony na true, spróbuj wszystkie warunki, aż warunekN zostanie pominięty. W uogólnionych słowach przy określaniu pierwszego PRAWDZIWE, wszystkie inne warunki połączone przez OR zostaną pominięte.

Rozważ drugi warunek

WHERE 1 = 0 AND 1 = 1

ponieważ pierwszy warunek jest oceniany FAŁSZYWY bez znaczenia dla oceny drugiego warunku, ponieważ jego ocena ma dowolną wartość w ogóle nie wpłynęłoby to na wynik, więc znowu była to dobra okazja dla serwera SQL do zaoszczędzenia czasu wykonania zapytania, pomijając niepotrzebne sprawdzanie stanu lub ocenę.

w przypadku "I" jeśli oceniany jest pierwszy warunek FAŁSZYWYcały łańcuch połączony z "I" zostanie uznany za oceniany jako FALSE bez oceniania innych.

condition1 AND condition2 AND ..... conditionN

jeśli oceniany jest warunek1 FAŁSZYWY, spróbuj wszystkich warunków do conditionN zostanie pominięty. W uogólnionych słowach przy określaniu pierwszego FAŁSZYWY, wszystkie inne warunki powiązane z I zostanie pominięty.

THEREFOR, WISE PROGRAMMER POWINIEN ZAWSZE PROGRAMOWAĆ ŁAŃCUCH WARUNKÓW W TAKIE SPOSÓB, W KTÓRYM NAJSZYBCIEJ LUB NAJBARDZIEJ ELIMINUJĄCY WARUNEK POTRZEBUJE PIERWSZE, LUB ZARZĄDZAJ WARUNKIEM W TAKIM SPOSÓB, KTÓRY MOŻE WYKORZYSTAĆ MAKSYMALNE ZALETY KRÓTKIEGO OBWODU

Dziękuję i pozdrawiam,

Rk_Hirpara


-2
2018-06-12 08:01



Przyczyna odrzucenia: zawsze testuj rzeczy na prawdziwym serwerze z rozsądnym zestawem danych. Na przykład, spróbuj tego bardziej realistycznego klauzuli where przy polu znaku - gdzie isnumeric (fieldname) = 1 AND convert (decimal, fieldname) <= 0 - okaże się, że ma błąd konwersji w wierszach gdzie isnumeric = 0, mimo że technicznie nie powinna potrzebować oceny drugiego warunku na takich rzędach. - Jasmine
Rzadko się zdarza, ale ta odpowiedź najwyraźniej jest zła. - Culme