在一些先决条件下,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按键之Menu详解

    Android手机一般都有三个键,返回键.Home键.菜单键: Android系统的菜单支持主要通过4个接口来实现. 从上图可以看出Menu是一个父类接口,它下面有两个子类一个是ContextMenu ...

  2. 深入了解STL中set与hash_set,hash表基础

    一,set和hash_set简介 在STL中,set是以红黑树(RB-Tree)作为底层数据结构的,hash_set是以哈希表(Hash table)作为底层数据结构的.set可以在时间复杂度为O(l ...

  3. Codeforces Round #379 (Div. 2) C. Anton and Making Potions 枚举+二分

    C. Anton and Making Potions 题目连接: http://codeforces.com/contest/734/problem/C Description Anton is p ...

  4. 北京地铁月度消费总金额计算(Python版)

    最近业余时间在学习Python,这是那天坐地铁时突发奇想,想看看我这一个月的地铁费共多少钱,所以简单的构思了下思路,就直接开写了,没想到用Python来实现还挺简单的. 设计思路: 每次乘车正常消费7 ...

  5. The Monty Hall Problem

    GNG1106 Lab 3The Monty Hall ProblemBackgroundThe Monty Hall Problem is a famous probability puzzle, ...

  6. Ecshop 最小起订量如何设置

    第一步,商品表必须有个字段  代表某个商品 最小订购数量->min_number 打开goods表   在最后字段添加一个min_number  tinyint类型 默认值为0  代表没有最小起 ...

  7. adding validation annotators to model classes 在linq to EntityFrame的Model中添加前台验证validation annotators

    The same solution can be applied for LINQ to SQL. The snippet the article shows for using the Metada ...

  8. 学习之路三十六:SQL知识总结 - [游标||字符串分割]

    好久没有写文章了,今天把前不久项目用到的SQL知识总结一下. 一丶字符串分割 SQL内置函数中是没有Split分割函数的,所以需要自己去实现,不多说,上代码: )) RETURNS @result T ...

  9. 读写文本(.txt)文件 .NET

    http://www.cnblogs.com/jx270/archive/2013/04/14/3020456.html (一) 读取文件 如果你要读取的文件内容不是很多,可以使用 File.Read ...

  10. 在Windows2008系统中利用IIS建立FTP服务器

    一.服务器管理器   1.2008的系统使用服务器管理器,选择角色,因为我之前已经开启了IIS服务器角色,所以我现在只要添加角色服务即可,如果你没有开启过的话,直接添加角色即可.   2.选择WEB服 ...