我正在执行我在这个站点上找到的脚本来标记我所有的表和存储过程以进行重新编译。
(我将其更改为也标记存储过程)
我有一个使用大量数据表的 Windows Forms (.net 3.5) 应用程序,在执行此脚本后,打开数据繁重的表单所需的时间从 8 秒缩短到 4 秒。
我必须定期运行这样的脚本吗?我认为 SQL Server 会负责编译过程等。
顺便说一句:这个问题应该放在 SO 上吗?我以为 DBA 会在 SF 上。
我正在执行我在这个站点上找到的脚本来标记我所有的表和存储过程以进行重新编译。
(我将其更改为也标记存储过程)
我有一个使用大量数据表的 Windows Forms (.net 3.5) 应用程序,在执行此脚本后,打开数据繁重的表单所需的时间从 8 秒缩短到 4 秒。
我必须定期运行这样的脚本吗?我认为 SQL Server 会负责编译过程等。
顺便说一句:这个问题应该放在 SO 上吗?我以为 DBA 会在 SF 上。
来自微软:
“由于添加索引或更改索引列中的数据等操作更改了数据库,因此应通过重新编译来再次优化用于访问其表的原始查询计划。这种优化会在 Microsoft 之后第一次运行存储过程时自动发生SQL Server 重新启动。如果存储过程使用的基础表发生更改,也会发生这种情况。但如果添加了存储过程可能受益的新索引,则在 Microsoft SQL 下一次运行存储过程之前不会进行优化服务器重新启动。在这种情况下,强制存储过程在下次执行时重新编译会很有用
强制重新编译存储过程的另一个原因是在必要时抵消存储过程编译的“参数嗅探”行为。当 SQL Server 执行存储过程时,该过程在编译时使用的任何参数值都包含在生成查询计划中。如果这些值代表随后调用过程的典型值,则存储过程在每次编译和执行时都会从查询计划中受益。否则,性能可能会受到影响。”
考虑到在 SQL Server 中对 compile 这个词的使用与在普通应用程序中使用的不同。在普通应用程序中,代码被编译为机器语言就绪状态,因此不必在运行时进行解释。SQL Server 使用 compile 是为了确定执行查询的最佳执行计划。由于数据有可能不断变化,SQL Server 可能必须根据可用的索引、统计信息的质量等做出新的决定,所有这些都会影响执行计划。因此,每当执行存储过程时,SQL Server 都会确定它是否可以为该查询重新使用现有的执行计划,或者是否需要生成新的执行计划。当然,如果不存在计划,它会生成一个新计划。
顺便说一句,如果您考虑一下,这与 .NET 应用程序所做的并没有太大区别。.NET 应用程序编译为中间语言状态,但默认情况下仅在第一次运行时完全编译。
SP 编译时,其执行路径是固定的。它不能利用新索引或基于表大小的不同策略。重新编译允许它重新评估执行条件。
我在这里的经验并不丰富——但经验法则是让简单的 SP 每次都重新编译。仅在更复杂的情况下设置不编译