表变量,临时表

9.2 表变量、临时表

临时表分为局部临时表和全局临时表,分别以#以及##为表名前缀。局部临时表在会话间不能共享,在会话结束后,临时表会被删除;全局临时表在会话间是可共享的,当创建的会话关闭时,全局临时表也会被删除。

表变量,发现过许多误解,以为表变量是内存表,是存储在内存中的,其实表变量与临时表一样,都是存储在Tempdb中的,表变量是在SQL Server 2000时加入的,当初是为了解决临时表造成重编译的问题而添加的。做个简单的测试,如下面的语句代码清单9-1中所示,可以获取当前会话使用Tempdb的空间数量,新建一个会话1,首先执行一次查询,发现user_objects_alloc_page_count字段对应的值是0。创建一个临时表,并插入一条数据。如图9-1中所示,使用了1个数据页。

SELECT *

FROM sys.dm_db_session_space_usage AS ddssu WITH(NOLOCK)

WHERE [email protected]@SPID

GO

CREATE TABLE #tempSpace1(c1 CHAR(8000))

GO

INSERT INTO #tempSpace1 (c1)

VALUES (‘a‘)

GO

SELECT *

FROM sys.dm_db_session_space_usage AS ddssu WITH(NOLOCK)

WHERE [email protected]@SPID

GO

代码清单9-1 查看临时表Tempdb使用情况

图9-1 查看临时表Tempdb使用结果

相同的,创建一个具有相同类型字段的表变量,查看会话对表空间的作用情况,如图9-2中所示,也使用了一个数据页。表变量确实使用了Tempdb作为存储。既然两者都是存储在Tempdb中的,那么为何还会有两种类型的数据呢,对比一下图9-1与图9-2中所显示的user_objects_dealloc_page_count字段(该字段表示回收的用户空间的数据页个数),会发现,图9-1中字段的值是0,而图9-2中的值是1,也就是说,表变量已经被回收了。它们的区别,第一个,就是作用域不同。表变量是批处理级的,当批处理结束后,表变量就会被回收,而临时表是会话级的,只能显式地删除,或者会话关闭才会回收。

SELECT *

FROM sys.dm_db_session_space_usage AS ddssu WITH(NOLOCK)

WHERE [email protected]@SPID

GO

DECLARE @tempSpace TABLE(c1 CHAR(8000))

INSERT INTO @tempSpace (c1)

VALUES (‘a‘)

GO

SELECT *

FROM sys.dm_db_session_space_usage AS ddssu WITH(NOLOCK)

WHERE [email protected]@SPID

GO

SELECT *

FROM sys.dm_db_session_space_usage AS ddssu WITH(NOLOCK)

WHERE [email protected]@SPID

GO

代码清单9-2 查看表变量Tempdb使用情况

图9-2 查看表变量Tempdb使用结果

表变量与临时表,存在着几个较为明显的差异,前面提到了,表变量是为了处理临时表造成的执行计划频繁重新编译而引进的新的功能。接下来,研究一下,表变量如何避免重编译。

9.2.1 统计信息

表变量与临时最大的差异,同时也需要极为注意的是表变量是,没有办法创建统计信息。所以,如前面章节中所介绍的,查询优化器在分析执行计划的时候,对表变量使用"猜测"的方式来分析。这其中的好处就是,没有统计信息的更新,就不会造成执行计划的重编译的问题。

使用下面的语句(直接点击XML格式的数据行,可以打开执行计划的可视化界面),新建临时表,并插入200条数据,执行查询,并查看其执行计划关于表操作的详细信息,如图9-3中所示,在临时表的预估数据行一行信息中,是200条,它的统计信息是准确的。

CREATE TABLE #tempTable1(c1 CHAR(8000));

DECLARE @cnt INT=0;

WHILE(@cnt<200)

BEGIN

????INSERT INTO #tempTable1 (c1)VALUES(‘a‘);

????SET @cnt+=1;

END;

SET STATISTICS XML ON

SELECT *

FROM #tempTable1 AS ts

SET STATISTICS XML OFF

代码清单9-3 临时表统计信息

图9-3 临时表统计信息

下面的语句,可以查看表变量的详细情况,如图9-4中,预估行的数量只有1。对于SQL Server来说,表变量是没有统计信息的,所以SQL Server只能用"猜测"的方式来预估表变量的数据行,SQL Server会认为表变量都是小表,执行计划通常也只会用NESTED LOOP来处理表变量的联接查询。因此,在使用表变量的时候,建议只应用在小数据量的查询中。

DECLARE @tempTable1 TABLE(c1 CHAR(8000));

DECLARE @cnt INT=0;

WHILE(@cnt<200)

BEGIN

????INSERT INTO @tempTable1 (c1)VALUES (‘a‘);

????SET @cnt+=1;

END;

SET STATISTICS XML ON

SELECT * FROM @tempTable1 AS ts;

SET STATISTICS XML OFF

代码清单9-4 表变量统计信息

图9-4 表变量统计信息

9.2.2 索引

临时表的索引与普通物理的索引相同,可以在创建表的时候指定主键和唯一约束,同时也可以在表创建以后再添加、修改或删除其他索引。而表变量只能在定义变量的时候指定主键或唯一约束,表变量在声明以后,便不能再添加或删除任何索引。

9.2.3 表结构修改

临时表与普通物理表相同,在创建后,可以再增减字段,修改字段属性,增加或删除约束等。而表变量在声明后,便不能再做任何关于表结构的修改。这也是为了重编译而考虑的,因为在当初(SQL Server早期版本设计中)的设计中,表结构的变更是会引起执行计划的重编译的。

时间: 2024-11-17 14:41:54

表变量,临时表的相关文章

SQL Server 2008 表变量 临时表

最近做一个报表,其中 在报表中用到了存储过程,游标,cte表达式,临时表和表变量. 在游标中循环遍历cte中的数据,把对应的数据存放在变量里面,之后把变量插入到表变量中,游标结束后,想要根据存储过程的参数对表变量进行过滤时,问题就来了. 用动态sql拼接sql语句时,就会出错.提示时没有声明表变量. 其实,表变量不能运用在动态sql中.怎么办呢?我是把表变量中的数据插入到临时表中,之后 在动态sql中实用临时表进行拼接就可以了. 不知道 大家 有没有更好的想法. 注: 临时表 : #tablen

[转]表变量和临时表的比较

本文转自;http://www.cnblogs.com/CareySon/archive/2012/06/11/TableVariableAndTempTable.html 关于表变量是什么(和表变量不是什么),以及和临时表的比较让很多人非常困惑.虽然网上已经有了很多关于它们的文章,但我并没有发现一篇比较全面的.在本篇文章中,我们将探索表变量和临时表是什么(以及不是什么),然后我们通过使用临时表和表变量对其解密. 表变量 表变量在SQL Server 2000中首次被引入,那么,什么是表变量呢?

[MSSQL]表变量和临时表的区别

一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用).定义表变量的语句是和正常使用Create Table定义表语句的子集.只是表变量通过DECLARE @local_variable语句进行定义. 表变量的特征: 表变量拥有特定作用域(在当前批处理语句中,但不在任何当前批处理语句调用的存储过程和函数中),表变量在批处理结束后自

SQL Server中的临时表和表变量 Declare @Tablename Table

在SQL Server的性能调优中,有一个不可比面的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择.记得在给一家国内首屈一指的海运公司作SQL Server应用性能评估和调优的时候就看到过大量的临时数据集处理需求,而他们的开发人员就无法确定什么时候用临时表,什么时候用表变量,因此他们就简单的使用了临时表.实际上临时表和表变量都有特定的适用环境.先卖弄一些基础的知识:表变量变量都以@或@@为前缀,表变量是变量的一种,另外一种变量被称为标量(可以理

【T-SQL系列】临时表、表变量

原文:[T-SQL系列]临时表.表变量 临时表临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在.临时表在创建的时候都会产生SQL Server的系统日志,虽它们在Tempdb中体现,是分配在内存中的,它们也支持物理的磁盘,但用户在指定的磁盘里看不到文件. 临时表分为本地和全局两种,本地临时表的名称都是以“#”为前缀,只有在本地当前的用户连接中才是可见的,当用户从实例断开连接时被删除.全局临时表的名称都是以“##

SQL Server 表变量和临时表的区别

一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用).定义表变量的语句是和正常使用Create Table定义表语句的子集.只是表变量通过DECLARE @local_variable语句进行定义. 表变量的特征: 表变量拥有特定作用域(在当前批处理语句中,但不在任何当前批处理语句调用的存储过程和函数中),表变量在批处理结束后自

表变量和临时表的比较

关于表变量是什么(和表变量不是什么),以及和临时表的比较让很多人非常困惑.虽然网上已经有了很多关于它们的文章,但我并没有发现一篇比较全面的.在本篇文章中,我们将探索表变量和临时表是什么(以及不是什么),然后我们通过使用临时表和表变量对其解密. 表变量 表变量在SQL Server 2000中首次被引入,那么,什么是表变量呢?微软在BOL (Declare @local_variable)中定义其为一个类型为表的变量.它的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键

SQL Server中的临时表和表变量

在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择.记 得在给一家国内首屈一指的海运公司作SQL Server应用性能评估和调优的时候就看到过大量的临时数据集处理需求,而他们的开发人员就无法确定什么时候用临时表,什么时候用表变量,因此他们就简 单的使用了临时表.实际上临时表和表变量都有特定的适用环境. 先卖弄一些基础的知识: 表变量 变量都以@或@@为前缀,表变量是变量的一种,另外一种变量被称为标

T-SQL 之 表变量和临时表

一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯一约束,NULL约束和CHECK约束(外键约束不能在表变量中使用).定义表变量的语句是正常使用Create Table定义表语句的子集.只是表变量通过DECLARE @local_variable语句进行定义. 表变量的特征: 表变量拥有特定作用域(在当前批处理语句中,但不在任何当前批处理语句调用的存储过程和函数中),表变量在批处理结束后自动