Поведение SQL OR и оператора AND - PullRequest
1 голос
/ 21 февраля 2011

У нас есть следующее выражение как T-Sql Query:

Exp1 OR Exp2

Оценивается ли Exp2, когда Exp1 имеет значение True?Я думаю, что нет необходимости оценивать это.

Аналогично;for,

Exp1 AND Exp2

- это значение Exp2, если значение Exp1 ложно?

Ответы [ 4 ]

6 голосов
/ 21 февраля 2011

В отличие от некоторых языков программирования, вы не можете считать в коротких замыканиях в предложениях T-SQL WHERE. Это может произойти, а может и нет .

2 голосов
/ 21 февраля 2011

SQL Server не обязательно оценивает выражения в порядке слева направо.Порядок оценки контролируется планом выполнения, и план выбирается на основе общей оценочной стоимости всего запроса.Поэтому нет уверенности в том, что SQL выполнит тот тип оптимизации короткого замыкания, который вы описываете.Именно эта гибкость делает opimiser полезным.Например, может случиться так, что второе выражение в каждом случае может быть оценено более эффективно, чем первое (если оно проиндексировано или, например, подчинено некоторому ограничению).

SQL также использует трехзначную логику, что означаетчто некоторые правила эквивалентности, используемые в двухзначной логике, не применяются (хотя это не меняет конкретный пример, который вы описываете).

0 голосов
/ 21 февраля 2011

Операторы запросов SQL Server OR и AND являются коммутативными.Не существует собственного порядка, и оптимизатор запросов может свободно выбирать путь с наименьшими затратами для начала оценки.Как только план установлен, другая часть не оценивается, если результат предопределен.

Это знание допускает запросы типа

select * from master..spt_values
where (type = 'P' or 1=@param1)
  and (1=@param2 or number < 1000)
option (recompile)

, где схема оценки гарантирована для короткого замыканиякогда @param установлен в 1. Этот шаблон типичен для дополнительных фильтров.Обратите внимание, что не имеет значения, проверяются ли @params до или после другой части.

Если вы очень хорошо разбираетесь в SQL и точно знаете, что запрос лучше всего выполнить по определенному плану, вы можетеВ SQL Server используются операторы CASE, которые всегда оцениваются во вложенном порядке.Приведенный ниже пример заставит type='P' к всегда вычисляться первым.

select *
from master..spt_values
where
    case when type='P' then
        case when number < 100 then 1
    end end = 1

Если вы не верите порядку оценки последнего запроса, попробуйте это

select *
from master..spt_values
where
    case when type='P' then
        case when number < 0 then
            case when 1/0=1 then 1
    end end end = 1

Несмотря на то, что константы в выражении 1/0=1 являются наименьшей стоимостью для оценки, они НИКОГДА не оцениваются - в противном случае запрос привел бы к делению на ноль вместо того, чтобы не возвращать строки (в master нет строк)..spt_values, соответствующие обоим условиям).

0 голосов
/ 21 февраля 2011

SQL Server иногда выполняет логическое короткое замыкание, а иногда нет.

Это зависит от сгенерированного плана выполнения запроса.Выбранный план выполнения зависит от нескольких факторов, включая селективность столбцов в предложении WHERE, размер таблицы, доступные индексы и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...