【问题标题】:How to precompile stored procedures in SQL server?如何在 SQL Server 中预编译存储过程?
【发布时间】:2010-11-06 02:55:25
【问题描述】:

有没有办法在 SQL Server 中预编译存储过程?我的要求是这样的。我有一些存储过程,编译时间比执行时间多。所以我想预编译所有的存储过程。在数据库服务器启动和运行时预编译它们会很好。

对此的任何想法都会非常有帮助!

【问题讨论】:

  • 你确定你不是在这里对一些并不真正需要的东西进行微优化吗,我从未见过在现实世界中需要这样的东西
  • 我有一个包含数十万条记录的表。因此启用了索引视图以更快地访问数据。这是对该表进行插入和更新的不利因素。所以我负责插入的存储过程在第一次执行时需要很多时间。但后来它更快。我发现 sp 在编译和准备执行计划方面需要时间。一旦编译完成,它就足以插入记录。我可以通过预编译第一次获得这种快速性能吗?
  • 你真的在一张表上有一个索引视图吗?如果是,则在表上创建索引,不要创建索引视图。

标签: sql sql-server


【解决方案1】:

编写一个使用“SET FMTONLY ON”执行每个存储过程的脚本。

该过程将被编译,但在执行期间不会对 DB 进行永久性更改。您不能将其用于使用临时表(#table 语法)的过程。

这就是 Microsoft 在 Visual Studio 中确定存储过程的输出应该是什么的方式。

【讨论】:

  • 不,不是。它使用SET FMTONLY ON
  • 修改为使用“SET FMTONLY ON”解决方案。好主意,感谢您的评论和 -1。
【解决方案2】:

您可以强制重新编译,但直到下次运行时才会发生

EXEC SP_RECOMPILE YourProcedureName

more info here...

每次运行时强制重新编译:
创建过程 YourProcedureNameWITH RECOMPILE .....

这次强制重新编译:
EXEC YourProcedureName WITH RECOMPILE

here is a good article on Optimizing SQL Server Stored Procedures to Avoid Recompiles

and another...

EDIT 基于 OP 的 cmets:

你为什么不第一次用虚假数据手动运行它(在应用程序之外)(虽然不是那么虚假以至于执行计划很糟糕,谷歌:sql server parameter spoofing and sniffing),这可以强制编译,然后运行一些 sql 删除插入的内容。当用户第一次运行它时,它已经运行并且已经编译好了。

【讨论】:

  • 我尝试使用 sp_Recompile 选项。但是第一次执行sp时,会花费很多时间,以后就足够快了。第一次使用如何改进?
【解决方案3】:

如果您使用的是 SQL Server 2008,那么您可以使用计划指南来强制重复使用现有的、预编译的执行计划。

请参阅Understanding Plan Guides,了解更多详细信息,尤其是阅读“对象计划指南”

但是,我怀疑您的问题的根源在于您的存储过程中正在实施的流程逻辑,因此建议您将此作为性能调整的第一个检查点。

【讨论】:

  • 您好,我使用的是 Sql Server 2005,并且在存储过程中包含一个普通的插入语句。表上存在索引视图。所以准备执行计划很费时间。知道我们如何提前准备好所有这些并让 sp 准备好执行吗?
  • 您好,为了帮助我了解您的环境,您为什么使用索引视图而不是直接向基础表添加索引?您正在使用多少个索引视图?表上有多少个索引?
  • 这听起来确实是个问题。索引视图经常被误解为只是另一个索引。但它们确实创建了视图的物理表示。如果您插入到作为索引视图一部分的表中,那么您就是在自找麻烦。如果这是常规导入例程的一部分,则在导入之前禁用索引。导入后再次启用。
【解决方案4】:

是否可以只执行一次 SP 而不影响任何数据?如果是这样,那么您可能会找到一种在服务器启动时触发此 SP 的方法。

【讨论】:

    【解决方案5】:

    一个存储过程应该只在它被创建和第一次执行时编译(并且只创建一个查询计划)。

    如果你经常使用 WITH RECOMPILE,你应该停止。如果您这样做是为了强制重新计算查询计划,因为不同的参数在不同的查询计划中更有效地工作(如果这很重要,性能方面),那么您需要考虑为不同的查询计划创建不同的 SP,也许使用 " parent" SP 来决定调用哪个。但这不是一种无痛的运动。

    如果您的表确实属于亚百万行类别,那么我会最仔细地查看索引并保持统计数据最新,在安静的时间定期重新编译以保持查询计划的效率。一旦进入数千万或数亿行,就可能会经历重复的痛苦。

    【讨论】:

      【解决方案6】:

      现在编译时间很少。将此代码插入程序顶部,您自己看看编译需要多少时间。

      SET STATISTICS TIME ON
      GO
      

      您会发现编译时间通常在0ms 中给出,这意味着太小而无法打扰,而执行时间则在几十、几百甚至几千毫秒。

      【讨论】:

      • 无论您是否正确,如果您不打算回答 OP 提出的具体问题,则应该在评论中,而不是答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多