我有一个存储过程,它接受一个日期输入,如果没有传入任何值,则稍后将其设置为当前日期:
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
其他。
有没有人知道为什么会这样?