Короткое замыкание оператора Where SQL оценено?

Булевы выражения в коротком замыкании операторов Where SQL оценены?

Например:

SELECT * 
FROM Table t 
WHERE @key IS NULL OR (@key IS NOT NULL AND @key = t.Key) 

Если @key ЯВЛЯЕТСЯ NULL, оценивает к истинному, @key, NOT NULL И @key = t. Key оценен?

Если нет, почему нет?

Если Да, это гарантируется? Это - часть ANSI SQL или является этим конкретная база данных?

Если конкретная база данных, SqlServer? Oracle? MySQL?

135
задан bruno 23 August 2019 в 23:24
поделиться

9 ответов

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 Порядок оценки правил

[...]

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

70
ответ дан 23 November 2019 в 23:48
поделиться

Я думаю, что это один из случаев, когда я написал бы его так, как если бы он не закорачивался по трем причинам.

  1. Потому что для MSSQL это не решается с помощью поиска в BOL в очевидном месте, поэтому для меня это делает его канонически неоднозначным.

  2. , потому что, по крайней мере, тогда я знаю, что мой код будет работать. И что более важно, так же, как и те, кто придет за мной, так что я не собираюсь заставлять их беспокоиться об одном и том же вопросе снова и снова.

  3. Я пишу достаточно часто для нескольких продуктов СУБД, и мне не нужно запоминать различия, если я могу легко их обойти.

19
ответ дан 23 November 2019 в 23:48
поделиться

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

Некоторое время назад я столкнулся с тем же вопросом, и мои исследования действительно не дали мне однозначного ответа. Вы можете написать небольшой запрос, чтобы дать вам представление о том, что он работает, но можете ли вы быть уверены, что по мере увеличения нагрузки на базу данных таблицы будут увеличиваться, а в базе данных все будет оптимизировано и изменено, такой вывод будет держать. Я не мог и поэтому допустил ошибку из-за предосторожности и использовал условие CASE в WHERE для обеспечения короткого замыкания.

12
ответ дан 23 November 2019 в 23:48
поделиться

я не знаю о коротких замыканиях, но я бы написал это как оператор if-else

if (@key is null)
begin

     SELECT * 
     FROM Table t 

end
else
begin

     SELECT * 
     FROM Table t 
     WHERE t.Key=@key

end

, переменные всегда должны быть в правой части уравнения. это делает его саргным.

http://en.wikipedia.org/wiki/Sargable

2
ответ дан 23 November 2019 в 23:48
поделиться

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

7
ответ дан 23 November 2019 в 23:48
поделиться

I typically use this for optional parameters. Is this the same as short circuiting?

SELECT  [blah]
FROM    Emp
WHERE  ((@EmpID = -1) OR (@EmpID = EmpID))

This gives me the option to pass in -1 or whatever to account for optional checking of an attribute. Sometimes this involves joining on multiple tables, or preferably a view.

Very handy, not entirely sure of the extra work that it gives to the db engine.

3
ответ дан 23 November 2019 в 23:48
поделиться

Я думаю, что для SQL Server это зависит от версии, но мой опыт работы с SQL Server 2000 таков, что он все еще оценивает @key = t.Key, даже если @key имеет значение null. Другими словами, при оценке предложения WHERE не происходит эффективного короткого замыкания.

Я видел людей, рекомендующих структуру, подобную вашему примеру, в качестве способа выполнения гибкого запроса, в котором пользователь может вводить или не вводить различные критерии. Мое наблюдение состоит в том, что Key по-прежнему участвует в плане запросов, когда @key имеет значение null, и если Key индексируется, то он не использует индекс эффективно.

Этот вид гибкого запроса с различными критериями, вероятно, является одним из случаев, когда динамически создаваемый SQL действительно лучший путь. Если @key равен нулю, вы просто не

2
ответ дан 23 November 2019 в 23:48
поделиться

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

Бинарные булевы операторы являются коммутативными, что означает:

a AND b == b AND a
a OR  b == b OR  a
a XOR b == b XOR a

, поэтому нет никакой гарантии порядка порядка. Порядок оценки будет определяться оптимизатором запросов.

В языках с объектами могут быть ситуации, когда вы можете писать логические выражения, которые могут быть оценены только с помощью оценки короткого замыкания. Ваша конструкция примера кода часто используется на таких языках (C #, Delphi, VB). Например:

if(someString == null | someString.Length == 0 )
  printf("no text in someString");

Этот пример C # вызовет исключение, если someString == null , поскольку он будет полностью оценен. В оценке короткого замыкания, это будет работать каждый раз.

SQL работает только со скалярными переменными (без объектов), которые не могут быть инициализированы, поэтому нет способа записать логическое выражение, которое не может быть оценено. Если у вас есть какое-либо значение NULL, любое сравнение вернет false.

Это означает, что в SQL вы не можете написать выражение, которое оценивается по-разному в зависимости от использования короткого замыкания или полной оценки.

Если реализация SQL использует оценку короткого замыкания, то можно надеяться, что только ускорит выполнение запроса.


Это означает, что в SQL нельзя писать выражения, которые оцениваются по-разному в зависимости от использования короткого замыкания или полной оценки.

Если реализация SQL использует оценку короткого замыкания, то можно надеяться, что только ускорит выполнение запроса.


Это означает, что в SQL нельзя писать выражения, которые оцениваются по-разному в зависимости от использования короткого замыкания или полной оценки.

Если реализация SQL использует оценку короткого замыкания, то можно надеяться, что только ускорит выполнение запроса.

1
ответ дан 23 November 2019 в 23:48
поделиться

Это занимает дополнительные 4 секунды в анализаторе запросов, поэтому из того, что я вижу, ЕСЛИ даже не закорочен ...

SET @ADate = NULL

IF (@ADate IS NOT NULL)
BEGIN
    INSERT INTO #ABla VALUES (1)
        (SELECT bla from a huge view)
END

Было бы неплохо иметь гарантированный способ!

0
ответ дан 23 November 2019 в 23:48
поделиться