Как создать динамический выбор WHERE без COALESCE

Я обнаружил, что моя база данных SQL 2008 R2 действительно борется с функцией COALESCE, если она используется в поиске.

КОД:

where 
    i.id_categ = COALESCE(@id_categ, i.id_categ )
    and i.id_brand = COALESCE(@id_brand , i.id_brand )
    and i.id_model = COALESCE(@id_model , i.id_model )
    and i.id_type = COALESCE(@id_karoseria, i.id_type )
    and i.id_fuel = COALESCE(@id_palivo, i.id_fuel )
    and (i.year between @year_from and @year_to)
    and (i.price between @price_from and @price_to)

ДИНАМИЧЕСКИЕ переменные:

ALTER PROCEDURE [dbo].[spInzeratSelect]
     @id_categ int = null,
     @id_brand int = null,
     @id_model int = null,
     @id_fuel int = null,
     @id_type int = null,

Поиск должен работать с этими переменными или без них.

Ориентир:

  with COALESCE = Total Execution Time: 3582
  without COALESCE conditions = Total Execution Time: 13

Вы понимаете разницу...

Есть ли хорошее решение, как игнорировать COALESCE и создавать динамический выбор SQL с другим подходом?

Спасибо.


person feronovak    schedule 12.04.2011    source источник
comment
Взгляните на сообщение в блоге Гейл Шоу на Catch- все запросы.   -  person Joe Stefanelli    schedule 12.04.2011


Ответы (1)


В вашем очень специфичном случае вам следует заменить все ваши COALESCE параметры поиска следующим шаблоном:

 AND ( (@id_brand IS NULL) OR (i.id_brand = @id_brand) )

так далее

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

EDIT: По-видимому, этот подход также рекомендован в ссылке @Joe Stefanelli. Первоначально я переманил его у Эрланда Соммерскога.

EDIT2: И я всегда забываю упомянуть OPTION (RECOMPILE).

person Matthew    schedule 12.04.2011