2014-12-01 2 views
0

У меня есть параметризованная хранимая процедура. Одним из параметров является @aName, которому разрешено быть NULL и часто имеет значение NULL.Ускорение неэффективного фильтра

Запрос в хранимой процедуре содержит следующий фильтр:

AND Name LIKE ('%' + ISNULL(@aName,Name) + '%') 

Этот фильтр работает, но меня поражает, как неэффективная по следующей причине:

Если @aName равна нулю, то мы просто хотим Name = Name но мы получают Name LIKE ('%Name%').

Как я закорачивать фильтр так, что я получаю следующее:

  1. Если @aName равно нулю, то используйте Name = Name или 1=1.
  2. Если @aName не равно null, используйте Name LIKE ('%Name%').
+1

Вы можете добавить 'OPTION (RECOMPILE)', чтобы заставить его принять во внимание фактическое значение переменной, хотя вам, вероятно, все равно придется писать его как 'AND (@aName IS NULL ИЛИ Name LIKE ('%' + @ aName + '%')) ' –

+0

@MartinSmith добавлен. Нужно ли мне скрывать старые сохраненные планы или нужно добавить подсказку? – whytheq

ответ

4

Запрос, который вы думаете есть:

AND (@aName IS NULL OR Name LIKE ('%' + @aName + '%')) 

Я не думаю, что будет большая разница скорости.

Вы можете также «разворачивать» весь запрос:

IF (@aName IS NULL) 
BEGIN 
    SELECT . . . 
    FROM . . . 
    WHERE . . . 
END; 
ELSE 
    SELECT . . . 
    FROM 
    WHERE . . . AND 
      LIKE ('%' + @aName + '%') 
END; 

Это будет иметь преимущество оптимизации для первой версии.

+0

Я развернул точку - в сценарии у нас есть три условия, подобные этому, так что полное развертывание будет означать множество возможных операторов IF, охватывающих разные перестановки. – whytheq

+0

Из-за того, что SQL Server выполняет обнуление параметров, БД стремится оптимизировать на основе любого параметра, переданного в процедуру в первый раз. Это означает, что время, которое вы запустили, может иметь большую разницу (например, подсчет населения Род-Айленда против Техаса ...) –

+0

@ Clockwork-Muse подскажет «С РЕКОМПИЛОМ», возможно, поможет? Если это не поможет, что мне делать? – whytheq

3

только проверить, является ли имя как @aName когда @aName не null.

AND (@aName is null or Name LIKE '%' + @aName + '%') 
Смежные вопросы