【问题标题】:SQL poor stored procedure execution plan performance - parameter sniffingSQL 存储过程执行计划性能不佳——参数嗅探
【发布时间】:2010-11-03 16:35:33
【问题描述】:

我有一个存储过程,它接受一个日期输入,如果没有传入任何值,则稍后将其设置为当前日期:

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(而不是由 IF 设置为 CURRENT_TIMESTAMP声明)

我发现禁用参数嗅探(通过欺骗参数)可以解决我的问题:

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

我知道这与参数嗅探有关,但我看到的所有“参数嗅探变坏”的示例都涉及使用传入的非代表性参数编译存储过程,但是在这里我' m 看到执行计划对于 SQL 服务器可能认为参数在执行语句时可能采用的所有可能值(NULLCURRENT_TIMESTAMP 或其他方式)都很糟糕。

有没有人了解为什么会发生这种情况?

【问题讨论】:

  • 这很有趣,但你实际上并没有在这里问任何问题......

标签: sql sql-server tsql sql-execution-plan parameter-sniffing


【解决方案1】:

基本上是的 - SQL Server 2005 的参数嗅探(在某些补丁级别中)被严重破坏。我见过的计划实际上永远不会完成(在一个小数据集上的几个小时内),即使对于小(几千行)数据集,一旦参数被屏蔽,这些数据集在几秒钟内完成。这是在参数始终为相同数字的情况下。我要补充一点,在我处理这个问题的同时,我发现了很多关于 LEFT JOIN/NULLs 没有完成的问题,我用 NOT IN 或 NOT EXISTS 替换了它们,这解决了计划的问题。同样,一个(非常糟糕的)执行计划问题。在我处理这个问题的时候,DBA 不会给我 SHOWPLAN 访问权限,而且由于我开始屏蔽每个 SP 参数,我没有任何进一步的执行计划问题,我必须深入研究这个问题才能完成.

在 SQL Server 2008 中,您可以使用 OPTIMIZE FOR UNKNOWN

【讨论】:

    【解决方案2】:

    我能够在 (SQL Server 2005) 中解决此问题的一种方法是添加查询优化器提示,而不是仅仅通过重新声明本地参数来屏蔽参数。

    这是一篇很好的博文,详细介绍了它: Parameter Sniffing in SqlServer 2005

    我使用:OPTION(优化 (@p = '-1'))

    【讨论】:

      【解决方案3】:

      在procedure里面声明procedure参数,把外部参数传给内部..compile..

      【讨论】:

      • 欢迎来到 SO @MjkSoft。请您编辑您的答案以包含一个示例来帮助提出问题的人。
      猜你喜欢
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多