重新编译存储过程

在执行诸如添加索引或更改索引列中的数据等操作更改了数据库时,应重新编译访问数据库表的原始查询计划以对其重新优化。在 SQL Server 重新启动后第一次运行存储过程时自动执行此优化。当存储过程使用的基础表发生变化时,也会执行此优化。但如果添加了存储过程可能从中受益的新索引,将不自动执行优化,直到下一次 SQL Server 重新启动后再运行该存储过程时为止。在这种情况下,强制在下次执行存储过程时对其重新编译会很有用。

必要时,强制重新编译存储过程的其他原因会阻碍存储过程编译的“参数查找”行为。当 SQL Server 执行存储过程时,该过程在编译时使用的任何参数值都作为生成查询计划的一部分包括在内。如果这些值就是后来调用存储过程时使用的典型值,则该存储过程在每次编译和执行时都会从查询计划中获益。否则,性能可能会受到影响。

SQL Server 2008 R2 具有对存储过程执行语句级重新编译的特点。当 SQL Server 2008 R2 重新编译存储过程时,只编译导致重新编译的语句,而不编译整个过程。因此,SQL Server 重新生成查询计划时,使用重新编译过的语句中的参数值。这些值可能与那些原来传递至过程中的值不同。

强制重新编译存储过程

SQL Server 中,强制重新编译存储过程的方式有三种:

  • sp_recompile 系统存储过程强制在下次执行存储过程时对其重新编译。具体方法是:从过程缓存中删除现有计划,强制在下次运行该过程时创建新计划。

  • 创建存储过程时在其定义中指定 WITH RECOMPILE 选项,指明 SQL Server 将不为该存储过程缓存计划,在每次执行该存储过程时对其重新编译。当存储过程的参数值在各次执行间都有较大差异,导致每次均需创建不同的执行计划时,可使用 WITH RECOMPILE 选项。此选项并不常用,因为每次执行存储过程时都必须对其重新编译,这样会导致存储过程的执行变慢。

    如果只想在要重新编译的存储过程而不是整个存储过程中执行单个查询,请在要重新编译的每个查询中指定 RECOMPILE 查询提示。此行为类似于本节前面中所述的 SQL Server 语句级重新编译行为,但除了使用存储过程的当前参数值外,RECOMPILE 查询提示还在编译语句时使用存储过程中本地变量的值。请仅在属于存储过程的查询子集中使用非典型值或临时值时使用此选项。有关详细信息,请参阅查询提示 (Transact-SQL)

  • 可以通过指定 WITH RECOMPILE 选项,强制在执行存储过程时对其重新编译。仅当所提供的参数是非典型参数,或自创建该存储过程后数据发生显著变化时,才应使用此选项。

    注意注意

    如果删除或重命名了存储过程所引用的对象,那么在执行该存储过程时会返回错误。但如果存储过程中引用的对象被同名的对象所替换,则无须重新创建即可执行该存储过程。

下次运行存储过程时对其重新编译