Jus*_*tin 10 sql t-sql sql-server parameter-sniffing sql-execution-plan
我有一个存储过程接受一个日期输入,如果没有传入值,则该日期输入稍后设置为当前日期:
CREATE PROCEDURE MyProc
@MyDate DATETIME = NULL
AS
IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP
-- Do Something using @MyDate
Run Code Online (Sandbox Code Playgroud)
我遇到问题,如果@MyDate
在NULL
第一次编译存储过程时传入if ,则对于所有输入值(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
Run Code Online (Sandbox Code Playgroud)
我知道这与参数嗅探有关,但我看到的所有"参数嗅探变坏"的例子都涉及使用传递的非代表性参数编译存储过程,但是在这里我看到了执行计划是可怕的SQL Server可能认为执行该语句其中参数可能需要在该点所有可能的值- NULL
,CURRENT_TIMESTAMP
或以其他方式.
有没有人知道为什么会这样?
基本上是 - 参数嗅探(在一些补丁级别)SQL Server 2005严重破坏.我已经看到计划实际上永远不会完成(在小数据集上几小时内),即使是小的(几千行)数据集,一旦参数被屏蔽,这些数据集在几秒钟内完成.这是在参数始终为相同数字的情况下.我想补充一点,在我处理这个问题的同时,我发现LEFT JOIN/NULL没有完成时会遇到很多问题,我用NOT IN或NOT EXISTS替换它们,这就把计划解决了.同样,(非常糟糕的)执行计划问题.在我处理这个问题时,DBA不会给我SHOWPLAN访问权限,因为我开始屏蔽每个SP参数,所以我没有任何进一步的执行计划问题,我将不得不深入研究这个问题. .
在SQL Server 2008中,您可以使用OPTIMIZE FOR UNKNOWN
.
归档时间: |
|
查看次数: |
25066 次 |
最近记录: |