9

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

CREATE PROCEDURE MyProc 
    @MyDate DATETIME = NULL 
AS 
    IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP 
    -- Do Something using @MyDate 

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

Что же смущает то, что плохое выполнение плана, который генерируется в страшен даже тогда, когда значение @MyDate используется фактическиNULL (и не установлен CURRENT_TIMESTAMP заявлением IF)

Я ве обнаружил, что отключение параметра нюхает (от подмены параметра) фиксирует мою проблему:

CREATE PROCEDURE MyProc 
    @MyDate DATETIME = NULL 
AS 
    DECLARE @MyDate_Copy DATETIME 
    SET @MyDate_Copy = @MyDate 
    IF @MyDate_Copy IS NULL SET @MyDate_Copy = CURRENT_TIMESTAMP 
    -- Do Something using @MyDate_Copy 

Я знаю, что это что-то делать с параметром нюхает, но все примеры, которые я видел в «параметре нюхает испортился» включили хранимую процедуру ing, скомпилированный с не представительным параметром, переданным, но здесь я вижу, что план выполнения ужасен для всех мыслимых значений, которые SQL-сервер может считать, что этот параметр может принимать значение в точке, где выполняется оператор - NULL, CURRENT_TIMESTAMP или иным образом ,

У кого-нибудь есть представление о том, почему это происходит?

+1

Это интересно, но вы не на самом деле задавая вопрос где-нибудь здесь ... – cjk

+0

Только что заметил, что :-) – Justin

ответ

6

В принципе да - параметр sniffing (на некоторых уровнях патчей) SQL Server 2005 сильно сломан. Я видел планы, которые фактически никогда не заканчиваются (в течение нескольких часов на небольшом наборе данных) даже для небольших (несколько тысяч строк) наборов данных, которые заканчиваются через несколько секунд после того, как параметры замаскированы. И это в тех случаях, когда параметр всегда был одинаковым. Я бы добавил, что в то же время я имел дело с этим, я обнаружил много проблем с LEFT JOIN/NULL, которые не были завершены, и я заменил их NOT IN или NOT EXISTS, и это разрешило план для чего-то, что будет завершено. Опять же, (очень плохой) план выполнения. В то время, когда я имел дело с этим, администраторы баз данных не предоставили мне доступ SHOWPLAN, и поскольку я начал маскировать каждый параметр SP, у меня не было каких-либо дальнейших проблем с планом выполнения, в которых мне пришлось бы копаться в этом для отказа от выполнения ,

В SQL Server 2008 вы можете использовать OPTIMIZE FOR UNKNOWN.

0

Один из способов избежать этой проблемы (SQL Server 2005), а не просто маскировать параметры путем повторного использования локальных параметров - это добавить подсказки оптимизатора запросов.

Вот хороший блог, который говорит о нем: Parameter Sniffing in SqlServer 2005

я использовал: ВАРИАНТ (оптимизации (@p = '-1'))