Давайте рассмотрим эти два утверждения:
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 не замыкает накоротко, как это делается в других языках программирования, и вы ничего не можете сделать, чтобы его заставить.
Ответы:
В SQL Server нет гарантии, будут ли операторы обрабатываться в
WHERE
предложении или в каком порядке . Единственное выражение, которое допускает короткое замыкание оператора,CASE
-WHEN
. Ниже приводится ответ, который я разместил в Stackoverflow:Как SQL Server закорачивает ГДЕ оценку состояния
Для получения дополнительной информации проверьте первую ссылку в приведенной выше записи блога, которая ведет к другому блогу:
SQL Server короткое замыкание?
источник
case
небезопасноCASE
перерывы: dba.stackexchange.com/questions/12941/…В T-SQL
IF
оператор может закорачиваться, но вы не можете полагаться на него, оценивая выражения по порядкуисточник
SQL является декларативным языком программирования. В отличие, скажем, от C ++, который является обязательным языком программирования.
Т.е. вы можете сказать, что вы хотите в конечном результате, но вы не можете диктовать, как выполняется результат, все зависит от движка.
Единственный верный способ гарантировать «короткое замыкание» (или любой другой поток управления ) внутри
WHERE
- это использовать индексированные представления, временные таблицы и подобные механизмы.PS. Вы также можете использовать подсказки плана выполнения (чтобы «подсказать» движку, как выполнить запрос, какие индексы использовать и КАК их использовать), просто подумал, что я должен упомянуть об этом, пока мы обсуждаем эту тему ...
источник
1) - ИЛИ (любое одно или оба условия будут ИСТИННЫМИ)
если условие 1 ИСТИНА, то условие 2 также будет проверено, оно может быть ИСТИНА или ЛОЖЬ
--AND (оба условия должны быть ИСТИНА)
если условие 1 ЛОЖНО, то условие 2 не будет проверено
источник
WHERE
разделах.Единственный способ контролировать, как условия в предложении WHERE - это использовать скобки для их группировки.
сильно отличается от
источник
AND
имеет более высокий приоритет, чемOR
. Оба эквивалентны. То, что вы говорите, будет верно дляWHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = x
запроса. Смотрите тест SQL-Fiddle