Логічні оператори АБО І в умові та порядку умов, де БЕЗ


33

Розглянемо ці два твердження:

IF (CONDITION 1) OR (CONDITION 2)
...

IF (CONDITION 3) AND (CONDITION 4)
...

Якщо CONDITION 1це так TRUE, чи CONDITION 2буде перевірено?
Якщо CONDITION 3це так FALSE, чи CONDITION 4буде перевірено?

Що з умовами щодо WHERE: чи оптимізує двигун SQL Server усі умови в WHEREпункті? Чи повинні програмісти розміщувати умови в потрібному порядку, щоб бути впевненим, що оптимізатор SQL Server вирішує його правильно ?

ДОДАТО:

Дякую Джеку за посилання, сюрприз від коду 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

У цьому випадку виняток « Розділити на нуль» не збільшується.

ВИСНОВОК:

Якщо у C ++ / C # / VB є коротке замикання, чому його не може мати SQL Server?

Щоб справді відповісти на це, давайте подивимось, як обидва працюють з умовами. Усі C ++ / C # / VB мають коротке замикання, визначене в специфікаціях мови, щоб пришвидшити виконання коду. Навіщо турбуватися оцінювати умови N OR, коли перша вже є істиною або умовами M AND, коли перша вже помилкова.

Ми, як розробники, повинні усвідомлювати, що SQL Server працює інакше. Це система на основі витрат. Для отримання оптимального плану виконання нашого запиту процесор запитів повинен оцінити кожне, де умова, та призначити йому вартість. Потім ці витрати оцінюються в цілому, щоб створити поріг, який повинен бути нижчим, ніж визначений поріг, який має SQL Server для гарного плану. Якщо вартість нижча за визначений поріг, використовується план, якщо не весь процес повторюється знову з іншою сумішшю умовних витрат. Вартість тут - або сканування, або пошук, або об'єднання злиття, або хеш-з'єднання тощо. Через це коротке замикання, як це є в C ++ / C # / VB, просто неможливо. Ви можете подумати, що примусове використання індексу на стовпчику вважається коротким замиканням, але це не так. Це лише змушує використовувати цей індекс і тим самим скорочує перелік можливих планів виконання. Система все ще ґрунтується на витратах.

Як розробник, ви повинні знати, що SQL Server не робить короткого замикання, як це робиться в інших мовах програмування, і ви нічого не можете зробити для цього.


Звідки остаточний блок цитат? Чи можете ви додати посилання?
Нік Чаммас

Відповіді:


25

У SQL Server немає гарантій, якщо або в якому порядку виписки будуть оброблятися в WHEREпункті. Єдиний вираз, який дозволяє оператору короткого замикання, CASE- WHEN. Далі йде відповідь, яку я опублікував у Stackoverflow:

Як коротке замикання SQL Server, де оцінка стану

Це робиться тоді, коли тобі це здається, але не так, як ти відразу думаєш.

Як розробник, ви повинні знати, що SQL Server не робить короткого замикання, як це робиться в інших мовах програмування, і ви нічого не можете зробити для цього .

Для отримання більш детальної інформації перевірте перше посилання у вищевказаній статті блогу, що веде до іншого блогу:

Чи коротке замикання SQL Server?

Остаточний вердикт? Ну, у мене ще цього немає, але, напевно, можна з упевненістю сказати, що єдиний раз, коли ви можете забезпечити конкретне коротке замикання, це коли висловлюєте декілька умов КОЛИ в виразі CASE. За допомогою стандартних булевих виразів оптимізатор буде переміщувати речі так, як вважає за потрібне, на основі таблиць, індексів та даних, які ви запитуєте.


2
Мабуть, є деякі випадкові випадки (або помилка), де навіть case це не безпечно
Джек Дуглас

1
Я також демонструю інший випадок (га!), Коли CASEперерви: dba.stackexchange.com/questions/12941/…
Аарон Бертран


0

SQL - декларативна мова програмування. На відміну від, скажімо, C ++, що є обов'язковою мовою програмування.

Тобто ви можете сказати йому, що ви хочете в кінцевому результаті, але ви не можете продиктувати, як результат виконується, все залежить від двигуна.

Єдиний вірний спосіб гарантувати "коротке замикання" (або будь-який інший потік управління ) всередині WHERE- це використання індексованих подань, тимчасових таблиць та подібних механізмів.

PS. Ви також можете використовувати підказки щодо плану виконання (щоб "натякнути" двигуну, як виконати запит, які індекси використовувати та ЯК використовувати їх), я просто подумав, що я повинен це згадати, поки ми на цю тему ...


-4

1) - АБО (будь-яка одна або обидві умови будуть ПРАВИЛЬНІ)

якщо умова 1 - ПРАВИЛЬНА, тоді умова 2 також перевірятиметься, вона може бути або ПРАВИЛЬНОЮ, або ЛІЖНОЮ

--AND (обидві умови повинні бути ПРАВИЛЬНІ)

якщо умова 1 є НЕВЕРСЬКОЮ, умова 2 не перевірятиметься


"якщо умова 1 неправдива, умова 2 не перевірятиметься" Це неправда. Дивіться відповідь вище . SQL Server все ще може оцінити умову 2, оскільки він не виконує оцінку короткого замикання в WHEREпунктах.
Nick Chammas

-4

Єдиний спосіб контролювати умови роботи в пункті WHERE - використовувати дужки, щоб згрупувати їх разом.

WHERE Col1 = 'Something' AND Col2 = 'Something' OR Col3 = 'Something' and Col4 = 'Something'

дуже відрізняється від

WHERE (Col1 = 'Something' AND Col2 = 'Something') OR (Col3 = 'Something' and Col4 = 'Something')

Просто цікаво. Чим ці дві умови відрізняються? Різні результати, результативність, план виконання? Я думав, що вони будуть рівнозначними.
ypercubeᵀᴹ

З першим вам потрібно співставити Col1, Col4 та Col2 або Col3. У другому рядку збігаються Col1 і Col2 або вам потрібно співставити Col3 і Col4, але Col1 і Col4 ніколи не потрібно буде обидва оцінювати разом.
mrdenny

1
Ні, ви помиляєтесь. ANDмає вищий пріоритет ніж OR. Обидва рівноцінні. Те, що ви говорите, було б істинним для WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xзапиту. Дивіться тест SQL-
Fiddle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.