2014-12-14 1 views
9

Я работаю над оптимизацией некоторых сильно используемых хранимых процедур и сталкивался с сценарием, который вызвал вопрос, на который я не мог найти ответы: при оценке TSQL в хранимой процедуре SQL Server коротко замыкает заявление IF?Имеет ли SQL-запрос коротких замыканий IF?

Например, предположим, что хранимая процедура имеет код, подобный:

IF @condition1 = 1 
OR EXISTS(SELECT 1 FROM table1 WHERE column1 = @value1) 
... 

В этом случае делает SQL Server короткого замыкания оценки, так что EXISTS утверждение никогда не выполняется, когда предыдущий пункт имеет значение верно?

Если это никогда или только иногда происходит, то у нас есть переписывание впереди нас.

+2

Не гарантируется. Проверьте план выполнения, чтобы убедиться, что это происходит в вашем случае. –

+0

Спасибо, «не гарантировано» - это то, что я искал. Проблема в том, что эти хранимые процедуры выполняются на сотнях клиентских БД, поэтому, если план выполнения определяет это, мы не можем предположить, что он будет оцениваться одинаково в системе каждого клиента и должен быть переписан. –

+1

Если вы хотите гарантию на чугун, тогда разделение на несколько операторов 'if' будет делать это. Когда [я смотрел на это раньше] (http://stackoverflow.com/a/5543985/73226), я нашел несколько примеров того, что это не короткое замыкание. Вы могли бы также изучить использование операторов case. –

ответ

4

Даже если он работает, на него не следует полагаться. Заявление CASE - единственное, что заявляет в документации как короткое замыкание, но даже это не (или, по крайней мере, не было) всегда корпус (хи хи). Вот один bug, который, к счастью, был исправлен с SQL Server 2012 (см. Комментарии).

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

Understanding T-SQL Expression Short-Circuiting

и дискуссионный форум, связанный с этой статьей.

3

Хорошей новостью является то, что она кажется короткой замыкающей. Вот минимальный пример:

DECLARE @condition1 bit = 1 

IF (@condition1 = 1) OR EXISTS(SELECT 1 FROM sys.objects) 
    PRINT 'True' 
ELSE 
    PRINT 'False' 

Когда @condition установлен в 1, это план выполнения: 0 строк сканируется sys.objects

execution plan 1

когда @condition установлен в 0, то просмотрел sys.objects таблица:

execution plan 2

Но нет никакой гарантии, что это будет иметь место каждый раз.

Смежные вопросы