У меня есть хранимая процедура, которая принимает ввод даты, который позднее устанавливается на текущую дату, если в значение не передано:
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
Я знаю, что это как-то связано со сниффингом параметров, но все примеры, которые я видел, как "сниффинг параметров пошёл плохо", были связаны с тем, что хранимая процедура компилировалась с переданным нерепрезентативным параметром, однако здесь я ' Я вижу, что план выполнения ужасен для всех мыслимых значений, которые SQL-сервер может считать параметром в момент выполнения инструкции - NULL
, CURRENT_TIMESTAMP
или иначе.
Кто-нибудь понимал, почему это происходит?