【问题标题】:What factors can cause Stored Procedure Recompilation on SQL Server?哪些因素会导致 SQL Server 上的存储过程重新编译?
【发布时间】:2012-01-29 14:55:19
【问题描述】:

我应该注意哪些因素会导致过度的存储过程重新编译?

会导致存储过程重新编译的代码示例会很有用。目的是尽可能避免重新编译,这应该会提高性能。

导致不同输出(根据数据类型和/或列数)的动态 SQL 和变量路径似乎会带来问题。假设是否正确?还有其他例子吗?

编辑:我确实找到了另一个例子。在流控制语句中创建临时表将导致重新编译。

【问题讨论】:

标签: sql-server performance stored-procedures


【解决方案1】:

有几种方法可以确保重新编译存储过程:

  • 使用WITH RECOMPILE
  • 使存储过程动态化(想想exec()
  • sp_recompile 标记要重新编译的proc。
  • 更改缓存查询计划所依赖的架构
  • 致电DBCC FREEPROCCACHE
  • 在查询级别,可以使用 RECOMPILE 查询提示 (SQL 2008) 重新编译 proc 中的单个语句。

重新编译的因素

除了上面列出的硬因素之外,是什么导致存储过程重新编译?嗯,很多东西。其中一些与上面的列表交织在一起,但我想重新呈现它们,因为它可能并不明显。

  • 插入或删除大量数据(索引和表中的数据密度通常控制查询计划)
  • 重建索引(对基础对象的更改)
  • 创建/删除临时表(同样,基础 DML 更改)。
  • 查询计划过期(认为最近没用过,sql想清理内存使用)

这绝不是一份详尽的清单。无论您使用 SQL Server 多久,查询优化器都会不断发展并带来惊喜。但这里有一些可能有用的资源:

但等等 - 还有更多!

话虽如此,您问题中的假设是重新编译总是不利于性能。事实上,经常重新编译是好的。

那么你希望它什么时候重新编译?让我们看一个按姓氏搜索的 proc 示例。存储过程执行 'parameter sniffing' 是一种祝福(如果它对您有用),也是一种诅咒(如果它对您不利)。首先通过某人在Zebr% 上搜索zerbrowski。姓氏索引意识到这是非常具体的,并且会从一百万中返回 3 行——因此构建了一个执行计划。为低行结果编译 proc 后,下一个搜索是 S%。嗯,S 是您最常用的名称,匹配 100 万行中的 93,543 行。

【讨论】:

    【解决方案2】:

    某些 SET 选项可能导致存储过程重新编译,甚至在一次执行中多次重新编译!

    其中一些选项甚至可能不在 SP 中

    --this will cause recompilation
    SET concat_null_yields_null ON;
    EXEC spMyProc;
    

    在 SP 内部导致重新编译的一些选项:

    阿里萨博特

    ANSI_NULLS

    QUOTED_IDENTIFIER

    幸运的是,这不会导致重新编译:SET NOCOUNT ON;

    【讨论】:

      【解决方案3】:

      可选/可变数字参数也可能看起来像重新编译,因为计划是针对特定参数列表缓存的。

      如果语句通过连接转换为 SP(希望将来重用),则会提取值并对其进行参数化。

      如果这些参数包括调用者动态填充的 IN 子句等内容,则参数列表很少匹配,并且您会看到每次 IN 子句包含不同数量的值时生成的新计划。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多