Логические операторы ИЛИ И в условии и порядке условий в ГДЕ

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 ИЛИ, если первое уже верно, или условия М И, когда первое уже ложно.

Мы, как разработчики, должны осознавать, что SQL Server работает по-другому. Это система, основанная на затратах. Чтобы получить оптимальный план выполнения для нашего запроса, обработчик запросов должен оценить каждое условие и назначить ему стоимость. Затем эти затраты оцениваются как единое целое, чтобы сформировать порог, который должен быть ниже, чем определенный порог, который имеет SQL Server для хорошего плана. Если стоимость ниже определенного порога, используется план, если не весь процесс повторяется снова с другим сочетанием затрат на условия. Стоимость здесь - это либо сканирование, либо поиск, либо соединение слиянием, либо хеш-соединение и т. Д. Из-за этого короткое замыкание, как это доступно в C ++ / C # / VB, просто невозможно. Вы можете подумать, что принудительное использование индекса для столбца считается коротким замыканием, но это не так. Это только заставляет использовать этот индекс и тем самым сокращает список возможных планов выполнения. Система по-прежнему основана на стоимости.

Как разработчик, вы должны знать, что SQL Server не замыкает накоротко, как это делается в других языках программирования, и вы ничего не можете сделать, чтобы его заставить.

Гарик
источник
Откуда последний блок цитат? Не могли бы вы добавить ссылку?
Ник Чаммас

Ответы:

25

В SQL Server нет гарантии, будут ли операторы обрабатываться в WHEREпредложении или в каком порядке . Единственное выражение, которое допускает короткое замыкание оператора, CASE- WHEN. Ниже приводится ответ, который я разместил в Stackoverflow:

Как SQL Server закорачивает ГДЕ оценку состояния

Это происходит, когда хочется, но не так, как вы сразу думаете.

Как разработчик, вы должны знать, что SQL Server не выполняет короткое замыкание, как это происходит в других языках программирования, и вы ничего не можете сделать, чтобы заставить его .

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

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

Окончательный вердикт? Ну, на самом деле у меня его еще нет, но, вероятно, можно с уверенностью сказать, что единственный раз, когда вы можете обеспечить конкретное короткое замыкание, это когда вы выражаете несколько условий WHEN в выражении CASE. Со стандартными логическими выражениями оптимизатор будет перемещать вещи по своему усмотрению на основе таблиц, индексов и данных, которые вы запрашиваете.

MicSim
источник
2
Очевидно, есть некоторые крайние случаи (или ошибка), где даже case небезопасно
Джек Дуглас
1
Я также демонстрирую другой случай (ха!), Где CASEперерывы: dba.stackexchange.com/questions/12941/…
Аарон Бертран
0

SQL является декларативным языком программирования. В отличие, скажем, от C ++, который является обязательным языком программирования.

Т.е. вы можете сказать, что вы хотите в конечном результате, но вы не можете диктовать, как выполняется результат, все зависит от движка.

Единственный верный способ гарантировать «короткое замыкание» (или любой другой поток управления ) внутри WHERE- это использовать индексированные представления, временные таблицы и подобные механизмы.

PS. Вы также можете использовать подсказки плана выполнения (чтобы «подсказать» движку, как выполнить запрос, какие индексы использовать и КАК их использовать), просто подумал, что я должен упомянуть об этом, пока мы обсуждаем эту тему ...

Jitbit
источник
-4

1) - ИЛИ (любое одно или оба условия будут ИСТИННЫМИ)

если условие 1 ИСТИНА, то условие 2 также будет проверено, оно может быть ИСТИНА или ЛОЖЬ

--AND (оба условия должны быть ИСТИНА)

если условие 1 ЛОЖНО, то условие 2 не будет проверено

Ранджит Кумар
источник
«если условие 1 - ЛОЖЬ, то условие 2 не проверяется». Это не так. Смотрите ответ выше . SQL Server все еще может оценивать условие 2, поскольку он не выполняет оценку короткого замыкания в WHEREразделах.
Ник Чаммас
-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')
mrdenny
источник
Просто любопытно. Чем эти два условия отличаются? Разные результаты, производительность, план выполнения? Я думал, что они будут эквивалентны.
ypercubeᵀᴹ
С первым нужно сопоставить Col1, Col4 и Col2 или Col3. Во второй строке, чтобы сопоставить Col1 и Col2 или вам нужно сопоставить Col3 и Col4, но Col1 и Col4 никогда не нужно будет оценивать вместе.
Мрденный
1
Нет, ты ошибаешься. ANDимеет более высокий приоритет, чем OR. Оба эквивалентны. То, что вы говорите, будет верно для WHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = xзапроса. Смотрите тест SQL-Fiddle
ypercubeᵀᴹ