已知问题?:SQL Server 2005存储过程无法使用参数完成

您的基本SP使用默认参数:

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID AS int = 20081130
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] WITH RECOMPILE
    */
    -- Stuff here that depends on DATA_DT_ID
END

具有硬编码的本地的相同SP.

ALTER PROCEDURE usp_debug_works]
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_works] WITH RECOMPILE
    */

    DECLARE @DATA_DT_ID AS int
    SET @DATA_DT_ID = 20081130
    -- Stuff here that depends on DATA_DT_ID
END

您可以看到我放入(冗余,偶数)WITH RECOMPILE选项的位置,以避免参数嗅探(这在开发中从来没有必要,这个东西工作正常)

工作的那个在一两分钟内完成,另一个永远不会完成 – 只是坐在那里几个小时.

这个问题从未发生在开发服务器(build 9.00.3282.00)上,生产服务器构建为9.00.3068.00

我从procs中删除了所有类型的代码,试图找到仍然存在问题的最小版本,并且非常小心地保持SP的两个版本相同,除了那个参数.

我有很多其他SP参数,他们确实运行良好.我也DROPped并重新创建了SP.

有任何想法吗?

是的,我有一个DBA看着它,我没有SHOWPLAN或任何有用的生产权,看看是否有阻塞(如果一个人的计划导致锁升级,我猜 – 再次,唯一的区别是参数)

我已经查看了所有SQL Server构建信息,并且没有看到有关此问题的已知问题,所以在我弄明白或DBA发现它之前,我有点卡住了.

UPDATE

这也无法完成(这实际上是这些SP的正常形式 – 我只是设置了默认设置,以便在测试期间来回切换)

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID AS int
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] 20081130 WITH RECOMPILE
    */
    -- Stuff here that depends on DATA_DT_ID
END

然而,这一个完成(这可能作为一种解决方法,虽然我有大约25个这些SP修改哪些具有相同的形式):

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID_in AS int
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] 20081130 WITH RECOMPILE
    */

    DECLARE @DATA_DT_ID AS int
    SET @DATA_DT_ID = @DATA_DT_ID_in
    -- Stuff here that depends on DATA_DT_ID
END

最佳答案 尝试屏蔽输入参数.

我想重编译不起作用,因为在编译时被嗅探指定的默认值(编辑:或在第一次调用时发送的参数).所以,重新编译没有任何效果.

我已经看到了估计计划之间的巨大差异,只需将默认值从零更改为零,或者将零更改为NULL.

ALTER PROCEDURE [usp_debug_mightwork]
    @DATA_DT_ID AS int = 20081130
AS
BEGIN
    DECLARE @IDATA_DT_ID AS int
    SET @IDATA_DT_ID = @DATA_DT_ID
    -- Stuff here that depends on IDATA_DT_ID
END

我认为this article解释了……

…parameter values are sniffed during
compilation or recompilation…

编辑:

New link on query plans and parameters.它仍然是参数嗅探是否指定了默认值.

The WITH RECOMPILE option specified on
the GetRecentSales stored procedure
above does not eliminate the
cardinality estimation error

Kind of related article about constants and plans

点赞