Как создать динамический ГДЕ выбрать без COALESCE - PullRequest
1 голос
/ 12 апреля 2011

Я обнаружил, что моя база данных 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 с другим подходом?

Спасибо.

1 Ответ

2 голосов
/ 12 апреля 2011

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

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

и т. Д.

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

РЕДАКТИРОВАТЬ: По-видимому, этоподход рекомендуется в ссылке @Joe Stefanelli.Первоначально я брал это у Эрланда Соммерскога.

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

...