【问题标题】:SQL Server Temp table vs Table VariableSQL Server 临时表与表变量
【发布时间】:2011-08-09 04:54:11
【问题描述】:

我们客户的数据库管理员要求我们不要在报告存储过程 (#Table) 中使用临时表,而是使用表变量。

表变量比临时表效率低吗?

另外,如果我创建一个表为#table,而不是##table,则带有一个# 的表是一个会话表,而不是全局的##,对吗?当stored procedure 完成时,你不做DROP TABLE #table ...#table 仍然存在吗?如果它是基于会话的,那么我还能再次访问它吗?

【问题讨论】:

  • 注意:表变量没有统计信息,不参与事务。要记住的事情。
  • 很多人错误地认为表变量总是在内存中,而临时表进入 tempdb 并访问磁盘。这些都不是绝对正确的(它们实际上都进入 tempdb,如果可能,两者都将留在内存中,如果需要,两者都会溢出到磁盘)

标签: sql-server temp-tables


【解决方案1】:

与临时表相比,表变量可以减少存储过程的重新编译(请参阅 KB #243586 和 KB #305977),并且由于它们无法回滚,因此不必担心事务日志。

##table 属于全局临时表。是的 #table 不存在,因为它只在给定的范围内,你永远不会在给定的范围内访问它。

编辑

我还想指出 CTE(通用表表达式)的使用,因为它也可以作为临时表工作。 检查此答案以获取详细信息:Which are more performant, CTE or temporary tables?

【讨论】:

  • 考虑到“是的#table 不存在,因为它仅在给定范围内并且您永远不会在给定范围内访问它”的问题具有误导性。 #table 存在于会话范围内。因此,您可以从同一会话中调用的另一个存储过程再次访问它。这意味着它在被清理之前必须比表变量停留更长的时间。
【解决方案2】:

我不是 100% 确定你在问什么,因为你的标题提到了表变量,所以你被要求使用表变量,但是你的问题没有问任何关于表变量的问题......但是表变量的声明如下:

DECLARE @Banana TABLE 
(
  Id INT,
  Name VARCHAR(20)
)

【讨论】:

    【解决方案3】:

    如果在 SP 中创建了本地临时表 (#table),则在 SP 完成后将其删除。 BOL 说:

    临时表超出范围时会自动删除, 除非使用 DROP TABLE 显式删除:

    • 在存储过程中创建的本地临时表被删除 存储过程完成时自动执行。表可以 由存储的任何嵌套存储过程引用 创建表的过程。该表不能被引用 调用创建表的存储过程的进程。

    • 所有其他本地临时表在 当前会话结束。

    • 会话时会自动删除全局临时表 创建表结束并且所有其他任务已停止 引用它们。任务和表之间的关联是 仅在单个 Transact-SQL 语句的生命周期内维护。这 意味着全局临时表在完成时被删除 最后一个主动引用的 Transact-SQL 语句 创建会话结束时的表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 2011-06-01
      • 1970-01-01
      • 2011-02-08
      • 2012-02-13
      • 2018-02-24
      相关资源
      最近更新 更多