在一些先决条件下,SQL Server可以缓存临时表(cache Temp Tables)。缓存临时表意味着当你创建反复创建同个临时表时,SQL Server就可以重用它们。这会从整体上大幅度提高你的工作量(性能),因为SQL Server不需要访问内存里的特定页(PFSGAM,SGAM),经常访问这些页在工作量大的情况下会引起加锁竞争(Latch Contention)。Paul White有一篇很棒的文章详细描述这个情况,可以点此围观下。

临时表缓存的条件之一是不能在存储过程里混合使用DML(Data Manipulation Language 数据操作语言)和DDL(Data Definition Language 数据定义语言)语句。我们来看下面的代码:

 -- Create a new stored procedure
CREATE PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1),
Col2 CHAR(4000),
Col3 CHAR(4000)
) -- Create a unique clustered index on the previous created temp table
CREATE UNIQUE CLUSTERED INDEX idx_c1 ON #TempTable(Col1) -- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Woody', 'Tu')
SET @i += 1
END
END
GO

这里你通过DDL语句(CREATE UNIQUE CLUSTERED INDEX )创建了索引,这就是说你混合使用了DDL和DML语句。因此SQL Server不能缓存你的临时表。你可以从下面例子里的DMV sys.dm_os_performance_counters ,通过跟踪性能计数器Temp Tables Creation Rate 来验证:

 DECLARE @table_counter_before_test BIGINT;
SELECT @table_counter_before_test = cntr_value FROM sys.dm_os_performance_counters
WHERE counter_name = 'Temp Tables Creation Rate' DECLARE @i INT = 0
WHILE (@i < 1000)
BEGIN
EXEC PopulateTempTable
SET @i += 1
END DECLARE @table_counter_after_test BIGINT;
SELECT @table_counter_after_test = cntr_value FROM sys.dm_os_performance_counters
WHERE counter_name = 'Temp Tables Creation Rate' PRINT 'Temp tables created during the test: ' + CONVERT(VARCHAR(100), @table_counter_after_test - @table_counter_before_test)
GO

当你运行这个代码时,SQL Server需要创建1000个单独的临时表,这个从SSMS的输出窗口就可以看到。

通过PRIMARY KEY约束来强制UNIQUE CLUSTERED INDEX就很容易克服这个问题。在这个方式下,你没有混合使用DDL和DML语句,SQL Server最后也能缓存你的临时表。

 ALTER PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
Col2 CHAR(4000),
Col3 CHAR(4000)
) -- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Woody', 'Tu')
SET @i += 1
END
END
GO

当你重新执行刚才用来跟踪相关计数器的代码,可以看到SQL Server值创建了一次临时表并重用它了:

这个结论也意味着,当你创建额外的非聚集索引(Non-Clustered Indexes)时,SQL Server也不能缓存临时表,因为在你的存储过程里,你又一次混合使用DDL和DML语句。

但在SQL Server 2014里,你就可以克服这个限制,因为现在你可以在CREATE TABLE语句行里创建索引。来看下面的代码:

 ALTER PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
Col2 CHAR(100) INDEX idx_Col2,
Col3 CHAR(100) INDEX idx_Col3
) -- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Woody', 'Tu')
SET @i += 1
END
END
GO

如你所见,我在创建临时表本身的时候,就在临时表上直接创建2个额外的非聚集索引。又一次我们没有混合使用DDL和DML语句,SQL Server又一次可以缓存并重用你的临时表。

在SQL Server 2014里,在临时表上定义行内定义索引,避开混合使用DML和DDL语句,让临时表只创建一次并重用,是一个很棒的功能!

这个新功能怎样?欢迎在下面评论里告诉我。

参考文章:

https://www.sqlpassion.at/archive/2013/06/27/improved-temp-table-caching-in-sql-server-2014/

SQL Server 2014,改善的临时表缓存的更多相关文章

  1. SQL Server 2014里的缓存池扩展

    在今天的文章里我想谈下SQL Server 2014里引入的缓存池扩展(Buffer Pool Extensions).我们都知道,在SQL Server里,缓存池是主要的内存消耗者.当你从你存储里读 ...

  2. 看完SQL Server 2014 Q/A答疑集锦:想不升级都难!

    看完SQL Server 2014 Q/A答疑集锦:想不升级都难! 转载自:http://mp.weixin.qq.com/s/5rZCgnMKmJqeC7hbe4CZ_g 本期嘉宾为微软技术中心技术 ...

  3. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  4. SQL Server 2014新特性探秘(1)-内存数据库

    简介    SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQL PASS Summit 2012的开幕式时,微软就宣布 ...

  5. SQL Server 2014里的性能提升

    在这篇文章里我想小结下SQL Server 2014引入各种惊艳性能提升!! 缓存池扩展(Buffer Pool Extensions) 缓存池扩展的想法非常简单:把页文件存储在非常快的存储上,例如S ...

  6. SQL Server 2014新特性——基数评估(白皮书阅读笔记)

    基数评估 目录 基数评估 说明 基数评估准确的重要性 模型假设 启用新的基数评估 验证基数评估的版本 在迁移到新的基数评估前要测试 校验基数评估 偏差问题 需要手动处理的变化 避免因为新的CE造成性能 ...

  7. sql server 2014预览版发布

    MSDN发布sql server2014预览版,如下图: SQL Server 2014新特性: 微软SQL Server部门主管Eron Kelly介绍,通过将交易处理放到内存中进行,新的SQL S ...

  8. SQL Server 2014新特性——Buffer Pool扩展

    Buffer Pool扩展 Buffer Pool扩展是buffer pool 和非易失的SSD硬盘做连接.以SSD硬盘的特点来提高随机读性能. 缓冲池扩展优点 SQL Server读以随机读为主,S ...

  9. SQL Server 2014新特性——事务持久性控制

    控制事务持久性 SQL Server 2014之后事务分为2种:完全持久, 默认或延迟的持久. 完全持久,当事务被提交之后,会把事务日志写入到磁盘,完成后返回给客户端. 延迟持久,事务提交是异步的,在 ...

随机推荐

  1. Android UI系列-----EditText和AutoCompleteTextView

    在这篇随笔里将主要讲解一下EditText和AutoCompleteTextView这个控件 1.EditText 首先我们先简单来说说EditText这个控件,这个就相当于我们平常web开发中的文本 ...

  2. [算法导论]红黑树实现(插入和删除) @ Python

    class RBTree: def __init__(self): self.nil = RBTreeNode(0) self.root = self.nil class RBTreeNode: de ...

  3. Linux--U盘安装Ubuntu12.04

    前言 最近一直在研究Android内核驱动开发的相关事宜,使用VMware虚拟机虽然可以更方便的开发,但是对于开发环境硬件的要求还是比较高的,若用于开发,效率太低了,所以考虑使用单独PC去装载Linu ...

  4. .NET错误The 'targetFramework' attribute in the <compilation> element of the Web.config file is used only to target version 4.0 and later of the .NET Framework

    错误描述: The 'targetFramework' attribute in the <compilation> element of the Web.config file is u ...

  5. Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  6. String和包装类Integer\Double\Long\Float\Character 都是final类型

    String和包装类Integer\Double\Long\Float\Character\Boolean 都是final类型 不可以改变

  7. A CIRCULAR PROGRESSBAR STYLE USING AN ATTACHED VIEWMODEL

    This blog post describes how to re-template the Silverlight ProgressBar control to render a circular ...

  8. 删除.gitignore中的在version control中的文件

    如果有一个文件例如xyz在版本控制系统中,然后你发现这个文件不应该提交到git上,所以加了.gitignore文件并将其加入其中,但是git不会自动讲其从版本库中移除它.如果你只有一个文件,你可以使用 ...

  9. C语言函数可变长度参数剖析

    C语言中的很多函数的入参被定义为可变参数,最典型的 int printf (const char * fmt, ...) 要对其中的可变参数进行处理,就要用到va_list类型和 VA_START, ...

  10. VC 2010的重大变化

    auto 关键字具有新的默认含义.由于使用旧含义的情况很少见,因此大多数应用程序都不会受此更改影响. 引入了新的 static_assert 关键字,如果代码中已经存在具有某个名称的标识符,则此关键字 ...