SQL Server 2014,改善的临时表缓存

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

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

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

复制代码
 1 -- Create a new stored procedure
 2 CREATE PROCEDURE PopulateTempTable
 3 AS
 4 BEGIN
 5     -- Create a new temp table
 6     CREATE TABLE #TempTable
 7     (
 8         Col1 INT IDENTITY(1, 1),
 9         Col2 CHAR(4000),
10         Col3 CHAR(4000)
11     )
12 
13     -- Create a unique clustered index on the previous created temp table
14     CREATE UNIQUE CLUSTERED INDEX idx_c1 ON #TempTable(Col1)
15 
16     -- Insert 10 dummy records
17     DECLARE @i INT = 0
18     WHILE (@i < 10)
19     BEGIN
20         INSERT INTO #TempTable VALUES ('Woody', 'Tu')
21         SET @i += 1
22     END
23 END
24 GO
复制代码

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

复制代码
 1 DECLARE @table_counter_before_test BIGINT;
 2 SELECT @table_counter_before_test = cntr_value FROM sys.dm_os_performance_counters
 3 WHERE counter_name = 'Temp Tables Creation Rate'
 4 
 5 DECLARE @i INT = 0
 6 WHILE (@i < 1000)
 7 BEGIN
 8     EXEC PopulateTempTable
 9     SET @i += 1
10 END
11 
12 DECLARE @table_counter_after_test BIGINT;
13 SELECT @table_counter_after_test = cntr_value FROM sys.dm_os_performance_counters
14 WHERE counter_name = 'Temp Tables Creation Rate'
15 
16 PRINT 'Temp tables created during the test: ' + CONVERT(VARCHAR(100), @table_counter_after_test - @table_counter_before_test)
17 GO
复制代码

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

 

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

复制代码
 1 ALTER PROCEDURE PopulateTempTable
 2 AS
 3 BEGIN
 4     -- Create a new temp table
 5     CREATE TABLE #TempTable
 6     (
 7         Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
 8         Col2 CHAR(4000),
 9         Col3 CHAR(4000)
10     )
11 
12     -- Insert 10 dummy records
13     DECLARE @i INT = 0
14     WHILE (@i < 10)
15     BEGIN
16         INSERT INTO #TempTable VALUES ('Woody', 'Tu')
17         SET @i += 1
18     END
19 END
20 GO
复制代码

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

 

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

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

复制代码
 1 ALTER PROCEDURE PopulateTempTable
 2 AS
 3 BEGIN
 4     -- Create a new temp table
 5     CREATE TABLE #TempTable
 6     (
 7         Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
 8         Col2 CHAR(100) INDEX idx_Col2,
 9         Col3 CHAR(100) INDEX idx_Col3
10     )
11 
12     -- Insert 10 dummy records
13     DECLARE @i INT = 0
14     WHILE (@i < 10)
15     BEGIN
16         INSERT INTO #TempTable VALUES ('Woody', 'Tu')
17         SET @i += 1
18     END
19 END
20 GO
复制代码

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

 

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



本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4609427.html,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
7天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
47 10
|
1月前
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
|
2月前
|
SQL 缓存 关系型数据库
MySQL技能完整学习列表6、查询优化——3、查询缓存——4、SQL优化技巧
MySQL技能完整学习列表6、查询优化——3、查询缓存——4、SQL优化技巧
63 0
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之数据查询
【数据库SQL server】关系数据库标准语言SQL之数据查询
95 0
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之视图
【数据库SQL server】关系数据库标准语言SQL之视图
76 0
|
2月前
|
SQL 人工智能 算法
【数据库SQL server】传统运算符与专门运算符
【数据库SQL server】传统运算符与专门运算符
68 0
|
17天前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
15 0
|
7天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
64 6
|
8天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
11天前
|
SQL 安全 Java
SQL server 2017安装教程
SQL server 2017安装教程
14 1