在看SQL Server临时表和表变量的区别这篇文章前,先看下本站之前的两篇文章:
其实你只要仔细的看上面2篇文章,就能大致的了解临时表和表变量的区别了。
什么情况下使用临时变量?
对于较小的临时计算用的数据集推荐使用表变量;如果数据集比较大,在代码中用于临时计算,同时这种临时使用永远都是简单的全数据集扫描而不需要考虑优化,比如没有分组或者分组很少的聚合(COUNT、SUM、AVERAGE、MAX等),也可以考虑使用表变量。
另外一个需要考虑的是应用环境的内存压力,如果代码运行的实例很多,就要特别注意内存变量对内存的小号。
什么情况下使用临时表?
一般对于大的数据集推荐使用临时表,同事创建索引,或者通过SQL Server的统计数据自动创建和维护功能来提供访问SQL语句的优化,如果需要在多个用户会话间数据交换,临时表就是唯一的选择了。在SQL Server临时表的定义中,我们知道临时表是存放在tempdb中的,因此需要注意tempdb的调优。
为方便大家对比,本站下面列出了表变量和临时表区别的详细对比
特性 | 表变量 | 临时表 |
---|---|---|
作用域 | 当前批处理 | 当前会话,嵌套存储过程,全局:所有会话 |
使用场景 | 自定义函数,存储过程,批处理 | 自定义函数,存储过程,批处理 |
创建方式 | DECLARE statement only.只能通过DECLEARE语句创建 | CREATE TABLE 语句 SELECT INTO 语句. |
表名长度 | 最多128字节 | 最多116字节 |
列类型 | 可以使用自定义数据类型 可以使用XML集合 | 自定义数据类型和XML集合必须在TempDb内定义 |
Collation | 字符串排序规则继承自当前数据库 | 字符串排序规则继承自TempDb数据库 |
索引 | 索引必须在表定义时建立 | 索引可以在表创建后建立 |
约束 | PRIMARY KEY, UNIQUE, NULL, CHECK约束可以使用,但必须在表建立时声明 | PRIMARY KEY, UNIQUE, NULL, CHECK. 约束可以使用,可以在任何时后添加,但不能有外键约束 |
表建立后使用DDL (索引,列) | 不允许 | 允许. |
数据插入方式 | INSERT 语句 (SQL 2000: 不能使用INSERT/EXEC). | INSERT 语句, 包括 INSERT/EXEC. SELECT INTO 语句. |
Insert explicit values into identity columns (SET IDENTITY_INSERT). | 不支持SET IDENTITY_INSERT语句 | 支持SET IDENTITY_INSERT语句 |
Truncate table | 不允许 | 允许 |
析构方式 | 批处理结束后自动析构 | 显式调用 DROP TABLE 语句. 当前会话结束自动析构 (全局临时表: 还包括当其它会话语句不在引用表.) |
事务 | 只会在更新表的时候有事务,持续时间比临时表短 | 正常的事务长度,比表变量长 |
存储过程重编译 | 否 | 会导致重编译 |
回滚 | 不会被回滚影响 | 会被回滚影响 |
统计数据 | 不创建统计数据,所以所有的估计行数都为1,所以生成执行计划会不精准 | 创建统计数据,通过实际的行数生成执行计划。 |
作为参数传入存储过程 | 仅仅在SQL Server2008, 并且必须预定义 user-defined table type. | 不允许 |
显式命名对象 (索引, 约束). | 不允许 | 允许,但是要注意多用户的问题 |
动态SQL | 必须在动态SQL中定义表变量 | 可以在调用动态SQL之前定义临时表 |