"IF..ElseIf..Else" или "Where where" для определения результатов хранимой процедуры - PullRequest
0 голосов
/ 04 ноября 2010

У меня есть два следующих оператора SQL

Первый:

IF(@User_Id IS NULL)  
BEGIN  
      SELECT *
      FROM [UserTable]
END  
ELSE           
BEGIN                  
      SELECT *
   FROM  [UserTable] AS u
   WHERE  u.[Id] = @User_Id                  
END 

Второй:

SELECT  *
FROM [UserTable] AS u
WHERE (@User_Id IS NULL OR u.[Id] = @User_Id)

Оба этих запроса будут помещены в собственную хранимую процедуру. Я подозреваю, что оператор IF вызывает много перекомпиляций на SQL. Я сталкиваюсь либо с разделением каждой части оператора IF на свою собственную хранимую процедуру, либо с заменой всего оператора IF предложением WHERE (проиллюстрировано выше во втором операторе SQL)

У меня вопрос: в чем разница между двумя операторами с точки зрения производительности и как SQL будет обрабатывать каждый оператор?

Спасибо.

1 Ответ

0 голосов
/ 04 ноября 2010

Оба решения будут генерировать одинаковое количество компиляций.

Первое решение, которое оптимизатор запросов может составить наилучший план для каждого из двух разных запросов.Первый запрос (в ветви NULL IF) не так уж и хорош, но второй (в ветви NOT NULL идентификатора) можно оптимизировать, если существует индекс для столбца Id.

Но второе решение - это катастрофа оптимизации.Независимо от значения параметра @User_Id оптимизатор должен разработать план, который работает для любого значения параметра.Таким образом, независимо от значения @User_Id план будет всегда использовать сканирование неоптимальных таблиц.Обойти эту проблему просто невозможно, и это , а не параметр, сниффинг, как некоторые могут подумать.Это просто правильность плана, даже если значение во время генерации плана НЕ равно NULL, план должен работать , даже если параметр равен NULL, поэтому он не может использовать индекс наId.

Всегда, всегда, всегда используйте первую форму с явным IF.

...