zoukankan      html  css  js  c++  java
  • 第11/24周 重编译

    今天我想谈下性能调优培训里的重编译(Recompilations )。当你执行一个查询,SQL Server里另一个变动使你执行计划的剩余部分无效,就会发生重编译。在那个情况下SQL Server需要保证你执行计划的准确性,重编译就会被触发。重编译会给你的SQL Server带来额外的CPU开销。

    什么是重编译?

    首先我想展示下编译和重编译之间的区别。2个星期前,我们讨论了SQL Server里的编译。当查询优化器把提交的查询转化为实际执行计划时,编译就会发生。这就是说编译在查询执行开始就发生。

    另一方面,重编译在查询执行期间就会发生。因此SQL为了保证执行计划的准确性就重编译执行计划的剩余部分。如果执行计划里引用的索引在计划执行时被删除了。这就导致不可接受的结果。SQL Server触发重编译有2个类型:

    • 基于正确性的重编译(Correctness-based Recompilations)
    • 基于最优性能的重编译(Optimality-based Recompilations)

    我们来详细看下这2类重编译。当计划不再准确,就会发生基于正确性的重编译(Correctness-based Recompilations)。例如你的数据库架构发生改变(新增或删除索引,删除统计信息),或者你的SET选项发生改变。在那个情况下,重编译就是为了保证你计划的准确。

    如果你的统计信息发生改变,就会发生基于最优性能的重编译(Optimality-based Recompilations)。统计信息发生改变,一方面是SQL Server会自动更新你的统计信息,另一方面是你触发了统计信息的人为更新。那样的情况可以是书签查找正越过临界点,SQL Server需要引入全表/聚集索引扫描。

    我们现在再来详细看一个在查询执行期间,触发很多重编译的常见特殊情景——临时表(Temp Tables)!

    临时表(Temp Tables)

    是的,你没看错:当你与临时表(Temp Tables)打交道时,在SQL Server里你会引起重编译。我们来一个非常简单的存储过程定义:

     1 CREATE PROCEDURE DoWork
     2 AS
     3 BEGIN
     4    CREATE TABLE #TempTable
     5    (
     6       ID INT IDENTITY(1, 1) PRIMARY KEY,
     7       FirstName CHAR(4000),
     8       LastName CHAR(4000)
     9    )
    10    INSERT INTO #TempTable (FirstName, LastName)
    11    SELECT TOP 1000 name, name FROM master.dbo.syscolumns
    12    SELECT * FROM #TempTable
    13 END
    14 
    15 GO

    这个存储过程创建了一个简单的临时表,往它里面插入了几条记录,最后从表里获取几条记录。很简单,是不是?关键是这个存储过程在执行期间触发了2个重编译:

    • 第1个触发重编译是因为你创建了一个新的临时表。通过创建临时表你就在改变你的数据库架构。这个触发了基于正确性的重编译(Correctness-based Recompilations)
    • 当你执行SELECT语句时,你触发了第2个重编译。刚才你在临时表里插入了几条记录,因此SQL Server需要更新你的统计信息。这里你就引入了基于最优性能的重编译(Optimality-based Recompilations)

    如何避免这2个重编译呢?你可以使用表变量(Table Variables)代替临时表。用表变量的话,你就不再改变数据库架构了(它只是个变量),而且表变量是没有统计信息的。这2个重编译就消失了。但是当然,用表变量会引入另一个性能问题:因为它们没有统计信息,SQL Server总是估计它们只有1行,因此你的基数预估就会完全一塌糊涂。

    因此表变量在SQL Server里只有特殊使用情景:当你只和小量数据打交道时。当你和大量数据打交道时,你仍应该使用临时表,因为它们会给你准确的统计信息,你也可以在上面建立索引。缺点就是它们会触发重编译。

    小结

    今天我们讨论了性能调优培训里的重编译(Recompilations)如你所见,因为SQL Server需要保证你的执行计划的准确性才会有重编译发生。我们还看了重编译经常发生的特殊场景——临时表(Temp Tables)。探秘重编译(Recompilations)(1/2) 探秘重编译(Recompilations)(2/2)

    这些重编译可以通过使用表变量来解决,但这里你也要意识到带来的副作用。下星期我会谈下SQL Server里的并行执行计划(Parallel Execution Plans),里面会有很多有趣的事情发生。好好享受接下来的7天,到时候见! 

    围观PPT:

    0803_11_重编译.rar

  • 相关阅读:
    Redis详解
    Linux常用命令
    sqlserver 游标写法
    Flask总结
    HTTPS协议
    Django REST framework 简介
    Cookie和session
    利用rest-framework编写逻辑关系
    vuex
    jQuery和Bootstrap的优点
  • 原文地址:https://www.cnblogs.com/woodytu/p/4567158.html
Copyright © 2011-2022 走看看