SQL 存储过程预编译

存储过程的预编译功能: 存储过程创建生效时,会编译缓存一个存储过程的执行计划。

   存储过程是一段SQL语句和可选控制流语句的预编译集合。

 

预编译就是缓存一个执行计划(在存储过程创建时,查询优化器对其进行分析、优化,并给出一个最终的执行计划(存储在Plane Cache中)。这样,在执行过程时便可按照这个执行计划进行查找)。

 

预编译主要体现在存储过程中的复杂查询语句:每次执行时,不需要每次编译,直接根据预编译的执行计划进行查找。

但是有时存储过程中某些复杂的查询语句发生“变化”(数据发生量级变化,结构、索引等发生变化),这时根据预编译的执行计划并不能达到最优查找的目的,

那么就需要指明该复杂的SQL语句在执行时重新选取最优路径(重新通过查询分析器分析,找出最优查找路径)。

 

根本原因分析:

存储过程预编译问题。

所谓预编译,是指在存储过程创建时,查询优化器对其进行分析、优化,给出并缓存一个最终的执行计划。

在存储过程每次执行时,不需要再次编译,而是根据这个预编译的执行计划进行查找,来提高查询性能。

但是有时存储过程中某些查询语句中相关的表和数据发生”变化“(例如:数据发生量级变化,相关表结构、索引等发生变化),

造成执行计划准确度问题(即不是最优的查找路径)。这时再根据先前预编译的执行计划不能达到最优的查找目的,反而造成查询耗时增大。


举个例子:比如一本每天更新的材料。在第一次定稿时,我们编排了每个章节在哪一页这样的目录。
但是因为持续更新,有一天可能对之前的章节有删减(这样之前的目录就不准确了),造成根据之前编排的目录并不能准确定位要找的信息,反而增加了查找时间。

 

解决办法:

通过在查询语句后面指定 “OPTION (OPTIMIZE FOR UNKNOWN)”,来生成一个稳定、统一的执行计划。
“OPTIMIZE FOR UNKNOWN” 指示查询优化器在查询优化期间使用统计数据而不是初始值来确定局部变量的值,
这些值仅用于查询优化期间,而不会用于查询执行期间。

通俗的理解就是:在运行存储过程中,发现某个查询SQL耗时较长时,则不按照预先的执行计划查找,而是通过分析统计数据来确定查找路径;
对于按预先的执行计划查找顺利的SQL,仍然按照预编译的执行计划进行查找。

 

posted @ 2022-03-30 11:49  Mark.Yang  阅读(499)  评论(0编辑  收藏  举报