VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 数据库 > sql数据库 >
  • sql语句大全之重编译

今天我想谈下性能调优培训里的重编译(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:


相关教程