sql temp tables @tmp vs #tmp

时间:2010-11-04 20:46:40

标签: sql-server-2005

SQL 2005中两种类型的临时表@tmp vs #tmp之间的区别是什么? 并且是我不知道的其他类型?

感谢

5 个答案:

答案 0 :(得分:9)

#tmp是一个临时表,主要表现为真实表。它可以有索引,可以有统计信息,参与事务,优化器可以计算出正确的行估计值

@tmp是一个表变量。没有索引,没有统计信息,没有事务感知,优化器总是假定只有1行

否则,它们都是作用域(略有不同),在内存/缓存中,但上下文是tempdb,如果太大则会溢出到磁盘等

编辑:

关于表变量的键。他们使没有区别。没有统计数据,假设有一行。它会将表扫描更改为聚集索引扫描,这是相同的。检查任何查询计划和估计的行。

另外,请阅读此阅读What a difference a temp table makes over a table variable

  

我做的第一件事是在@ComputersToProcess表变量上放置一个主键。这使得表格扫描成为聚集索引扫描,但没有为性能做任何事情。

答案 1 :(得分:5)

请参阅http://support.microsoft.com/kb/305977

与临时表相比,表变量具有以下优点:

  • 正如SQL Server联机丛书“Tables”文章中提到的,表变量,例如局部变量,具有明确定义的范围,最后会自动清除它们
  • 与临时表相比,表变量导致存储过程的重新编译更少。
  • 涉及表变量的事务仅在表变量更新期间持续存在。因此,表变量需要较少的锁定和日志记录资源。由于表变量的范围有限且不属于持久性数据库,因此事务回滚不会影响它们

与临时表相比,这些是一些缺点:

  • 无法在表变量上创建非聚集索引,而不是为PRIMARY或UNIQUE约束创建的系统索引。与具有非聚集索引的临时表相比,这会影响查询性能。
  • 表变量不像临时表那样维护统计信息。无法通过自动创建或使用CREATE STATISTICS语句在表变量上创建统计信息。因此,对于大型表上的复杂查询,缺少统计信息可能会阻止优化程序确定查询的最佳计划,从而影响该查询的性能。
  • 在初始DECLARE语句之后无法更改表定义
  • 不能在INSERT EXEC或SELECT INTO语句中使用表变量。
  • 表格类型声明中的CHECK约束,DEFAULT值和计算列无法调用用户定义的函数。
  • 如果表变量是在EXEC语句或sp_executesql存储过程之外创建的,则不能使用EXEC语句或sp_executesql存储过程来运行引用表变量的动态SQL Server查询。由于表变量只能在其本地作用域中引用,因此EXEC语句和sp_executesql存储过程将超出表变量的作用域。但是,您可以创建表变量并在EXEC语句或sp_executesql存储过程中执行所有处理,因为表变量本地作用域位于EXEC语句或sp_executesql存储过程中。

与临时表或永久表相比,表变量是仅限内存的结构可以确保更好的性能,因为它们是在驻留在物理磁盘上的数据库中维护的吗?

  • 表变量不是仅内存结构。 因为表变量可能包含的数据超出内存容量,所以它必须在磁盘上有一个存储数据的位置。表变量在tempdb数据库中创建,类似于临时表。如果内存可用,则在内存(数据高速缓存)中创建和处理表变量和临时表。

对于实际的性能比较,另见:

答案 2 :(得分:2)

只需添加现有答案。实际上有 3 类型的临时表。除了其他答案之外,您还可以创建全局临时表,如##globalTempTable

这些对所有sql server连接都是可见的,并且很少使用,但是在注意到它们确实存在时很有用。

这里有一个关于标准和全局临时表之间差异的很好的阅读 http://www.codeproject.com/KB/database/TempTable.aspx

答案 3 :(得分:1)

@tmp是指存储在内存中的类型表变量,而#tmp是指TEMP数据库中的表。

答案 4 :(得分:0)

还有另一种类型的“临时表”我使用CTE就像创建临时表一样。