SQL Server中的临时表和表变量有什么区别?

在SQL Server 2005中,咱们可使用如下两种方式之一建立临时表: 数据库

declare @tmp table (Col1 int, Col2 int);

要么 服务器

create table #tmp (Col1 int, Col2 int);

二者之间有什么区别? 对于@tmp是否仍使用tempdb或内存中是否发生了全部事情,我有不一样意见。 网络

在哪种状况下赛过另外一种? session


#1楼

  1. 临时表:临时表易于建立和备份数据。 函数

    表变量:可是,当咱们一般建立普通表时,表变量会涉及工做量。 性能

  2. 临时表:临时表结果可由多个用户使用。 测试

    表变量:可是表变量只能由当前用户使用。 优化

  3. 临时表:临时表将存储在tempdb中。 它将产生网络流量。 当临时表中有大量数据时,它就必须跨数据库工做。 将存在性能问题。 spa

    表变量:可是表变量将在物理内存中存储一​​些数据,而后在大小增长时将其移到tempdb。 code

  4. 临时表:临时表能够执行全部DDL操做。 它容许建立索引,删除,更改等。

    表变量:表变量不容许执行DDL操做。 可是table变量只容许咱们建立聚簇索引。

  5. 临时表:临时表可用于当前会话或全局会话。 这样,多用户会话就能够利用表中的结果。

    表变量:可是表变量能够在该程序中使用。 (存储过程)

  6. 临时表:临时变量不能使用事务。 当咱们使用临时表进行DML操做时,它能够回滚或提交事务。

    表变量:可是咱们不能对表变量执行此操做。

  7. 临时表:函数不能使用临时变量。 此外,咱们没法在函数中执行DML操做。

    表变量:可是该函数容许咱们使用表变量。 可是使用表变量,咱们能够作到这一点。

  8. 临时表:当咱们为每一个后续调用使用temp变量时,存储过程将进行从新编译(不能使用相同的执行计划)。

    表变量:表变量不会那样作。


#2楼

@wcm-其实是要选择表变量,而不只仅是Ram-它能够部分存储在磁盘上。

临时表能够具备索引,而表变量只能具备主索引。 若是速度是一个问题,表变量可能会更快,可是很显然,若是有不少记录,或者须要搜索汇集索引的临时表,那么临时表会更好。

好背景文章


#3楼

对于全部相信temp变量仅在内存中的神话的人

首先,表变量不必定是驻留内存的。 在内存压力下,能够将属于表变量的页面推出到tempdb。

在这里阅读文章: TempDB ::表变量与本地临时表


#4楼

在哪种状况下赛过另外一种?

对于较小的表(少于1000行),请使用临时变量,不然请使用临时表。


#5楼

引用来自; 专业SQL Server 2012内部和故障排除

统计信息临时表和表变量之间的主要区别在于,不会在表变量上建立统计信息。 这有两个主要结果,首先是查询优化器对表变量中的行数使用固定估计,而不考虑其包含的数据。 此外,添加或删除数据不会改变估计值。

索引尽管能够建立约束,但没法在表变量上建立索引。 这意味着经过建立主键或惟一约束,您能够在表变量上具备索引(由于建立这些索引是为了支持约束)。 即便您有约束,所以索引也将具备统计信息,可是在编译查询时将不使用索引,由于它们在编译时将不存在,也不会致使从新编译。

模式修改能够在临时表上进行模式修改,但不能在表变量上进行模式修改。 尽管能够在临时表上进行模式修改,可是请避免使用它们,由于它们会致使从新编译使用该表的语句。

临时表与表变量

表变量未在内存中建立

常见的误解是表变量是内存结构,所以其执行速度要比临时表快 。 多亏了一个名为sys的DMV。 dm _ db _ session _ space _ usage,按会话显示tempdb的使用状况, 您能够证实并不是如此 。 从新启动SQL Server清除DMV后,运行如下脚原本确认您的会话_ id为用户_对象_分配_页面_ count返回0:

SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

如今,您能够经过运行如下脚原本建立临时表,并用一行填充并填充一行,以检查临时表使用了多少空间:

CREATE TABLE #TempTable ( ID INT ) ;
INSERT INTO #TempTable ( ID )
VALUES ( 1 ) ;
GO
SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

我服务器上的结果代表该表在tempdb中分配了一页。 如今运行相同的脚本,可是此次使用表变量:

DECLARE @TempTable TABLE ( ID INT ) ;
INSERT INTO @TempTable ( ID )
VALUES ( 1 ) ;
GO
SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

使用哪个?

是否使用临时表或表变量应该经过全面的测试来肯定,可是最好将临时 表做为默认表,由于 出错的地方 要少得多

我已经看到客户使用表变量开发代码,由于他们处理的是少许的行,而且比临时表要快,可是几年后,表变量中有成千上万的行,而且性能不好,所以请在作出决定时尝试进行一些容量规划!

相关文章
相关标签/搜索