zoukankan      html  css  js  c++  java
  • SQL 编译与重编译

    编译的含义

    当SQLSERVER收到任何一个指令,包括查询(query)、批处理(batch)、存储过程、触发器(trigger)

    、预编译指令(prepared statement)和动态SQL语句(dynamic SQL Statement)要完成语法解释、语句解释,

    然后再进行“编译(compile)”,生成能够运行的“执行计划(execution plan)”。在编译的过程中,

    SQLSERVER会根据所涉及的对象的架构(schema)、统计信息以及指令的具体内容,估算可能的执行计划,

    以及他们的成本(cost),最后选择一个SQLSERVER认为成本最低的执行计划来执行。执行计划生成之后,

    SQLSERVER通常会把他们缓存在内存里,术语统称他们叫“plan cache”以后同样的语句执行,SQLSERVER就可以使用同样的执行计划,而无须再做一次编译。

    这种行为叫“重用(reuse)或者叫重用执行计划”。但是有时候,哪怕是一模一样的语句,SQL下次执行还是要再做一次编译。

    这种行为叫“重编译(recompile)”。执行计划的编译和重编译都是要消耗资源的。

    如果执行计划能够重用,那么SQLSERVER就不需要再执行上面的过程,加快执行指令的速度.

    重编译的发生场景


    但是有些时候,SQLSERVER为了确保返回正确的值,或者有性能上的顾虑,有意不重用缓存在内存里的执行计划,而现场编译一份。

    这种行为,被称为重编译(recompile)。下面是比较常见的会发生重编译的情形:

    1、当指令或者批处理所涉及的任何一个对象(表格或者视图)发生了架构(schema)变化

    例如,在表或者视图上添加或删除了一个字段,添加或者删除了一个索引,在表上添加或者删除了一个约束条件(constraints)等。

    定义发生了变化,原来的执行计划就不一定正确了,当然要重编译

    2运行过sp_recompile

    当用户在某个存储过程或者触发器上运行过sp_recompile后,下一次运行他们就会发生一次重编译。

    如果用户在某个表或者视图上运行了sp_recompile,那么所有引用到这张表(或者视图)的存储过程在下一次运行前,都要做重编译

    3、有些动作会清除内存里的所有执行计划,迫使大家都要做重编译

    例如,下列动作会清除整个SQLSERVER服务器缓存的所有执行计划:

    (1)Detach一个数据库

    (2)对数据库做了升级,在新的服务器上,会发生执行计划清空

    (3)运行了DBCC freeproccache

    (4)运行了reconfigure语句

    (5)运行了alter database..collate语句修改了某个数据库的字符集(collation)

    下列动作会清除SQLSERVER服务器缓存的某个数据库的执行计划:

    DBCC FLUSHPROCINDB

    清除SQL Server 2000服务器内存中的某个数据库的存储过程缓存内容

    1 DECLARE @a INT
    2 SELECT @a=DB_ID('gposdb')
    3 DBCC flushprocindb(@a)

    ALTER DATABASE ...MODIFY NAME语句

    ALTER DATABASE ...SET ONLINE语句

    ALTER DATABASE...SET OFFLINE语句

    ALTER DATABASE...SET EMERGENCY语句

    DROP DATABASE 语句

    当一个数据库自动关闭时

    DBCC CHECKDB语句结束时

    4、当下面这些SET 开关值变化后,先前的那些执行计划都不能重用

    ansi_null_dflt_off,

    ansi_null_dflt_on,

    ansi_nulls,

    _ansi_padding

    ansi_warnings,

    arithabort,

    concat_null_yields_null,

    datefirst,dateformat,

    forceplan,

    language,

    no_browsetable,

    numeric_roundabort,

    quoted_identifier

    这是因为这些SET开关会影响语句的执行的行为,甚至带来不同的结果。他们发生变化了,SQLSERVER就要根据新的设置重做执行计划

    往往存储过程使用一段时间就会出现查询慢的情况,可以使用重编译或者删除重建的方法处理。

    1 Create procedure usp_test 
    2 @a INT
    3 WITH RECOMPILE 
    4 
    5    
    6     as 
    7     
    8     SELECT 1

    原文出自 http://www.cnblogs.com/lyhabc/archive/2013/01/17/2865290.html

  • 相关阅读:
    Path Sum II
    Convert Sorted Array to Binary Search Tree
    Construct Binary Tree from Inorder and Postorder Traversal
    Construct Binary Tree from Preorder and Inorder Traversal
    Maximum Depth of Binary Tree
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Same Tree
    Validate Binary Search Tree
    Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/jerrywublogs/p/4903665.html
Copyright © 2011-2022 走看看