SQL Server中的本地和全局临时表


156

SQL Server中的本地和全局临时表有什么区别?


2
这是一些有关此的摘要详细信息,请单击此处
Jayesh Sorathia 2012年

5
使用表变量时要小心。如果在查询中使用它们,由于未编制索引,它们可能会导致查询计划出现严重的性能问题。

实际上,可以根据需要对临时表进行索引,但这也需要时间和资源,因此仍然可能导致性能或资源问题。
安德鲁·斯蒂兹

Answers:


114

我发现这个解释很清楚(它是Technet的纯副本):

临时表有两种类型:本地和全局。与第一次创建或引用表时,在与SQL Server实例相同的连接期间,本地临时表仅对其创建者可见。用户从SQL Server实例断开连接后,将删除本地临时表。全局临时表对任何用户和创建后的任何连接都是可见的,并且在引用该表的所有用户与SQL Server实例断开连接时,它们都会被删除。


好极了,很有帮助的答案!我正在寻找有关是否/何时由SQL Server自动清除全局临时表的特定信息。
kwill

答案非常清楚简洁。谁能想到全局临时表的好用例?与本地临时表的目的形成对比的一个例子说明了他们的目的?
特雷弗

335
  • 表变量DECLARE @t TABLE)仅对创建它的连接可见,并且在批处理或存储过程结束时将其删除。

  • 本地临时表CREATE TABLE #t)仅对创建它的连接可见,并在关闭连接时被删除。

  • 全局临时表CREATE TABLE ##t)对所有人都是可见的,并且在引用它们的所有连接都关闭时将其删除。

  • Tempdb永久表USE tempdb CREATE TABLE t)对所有人都是可见的,并且在服务器重新启动时将被删除。


55
还要指出:关闭本地临时表的作用域时,它们会被删除。因此,如果您在存储过程中创建本地临时表,然后尝试在该存储过程之外访问它-它将不存在。

为Will +1。我试图将本地临时表用作优化程序,并且试图将存储过程用作“创建并填充(如果不存在)”初始化程序。如您所说,除非您使用全局临时表,否则它不起作用。
拆线器

9
“当所有引用它们的连接都关闭时,将被删除”-“引用它们的连接”到底是什么意思?如果一个连接1的StoredProc创建了一个## TempTable,我可以在10分钟后从另一个连接2看到它吗(如果该连接2在表创建时处于活动状态?)答案:全局临时表会在创建时自动删除。创建表的会话结束,所有其他任务已停止引用它们。(请参阅此页面上更多的其他答案)
tbone 2014年

我尝试使用存储过程创建后续逻辑所需的本地临时表(#t),但是事实证明,父存储过程必须创建它们,以便子存储过程调用可以使用它们。这是一件可悲的事情,因为我们有一堆存储过程,它们必须以相同的方式设置表并调用通用的存储过程。在子调用可以访问由同级创建的表的情况下,全局临时表是否可以工作?我们正在使用SQL Server2008。–
Brandon

1
@布兰登你说得对。那是缺少功能。TSQL支持对临时数据进行适当的范围界定是很粗略的。语言设计师似乎希望一切都具有全球性。而且几乎不支持闭包。您可以传递一个游标变量。但这是另一种蠕虫,因为逐行排行是不可能的。
安东尼·法尔

12

1.) 本地临时表仅在连接期间存在,或者,如果在复合语句中定义,则在复合语句期间存在。

本地临时表仅可用于创建表的SQL Server会话或连接(表示单个用户)。当创建表的会话关闭时,这些将自动删除。本地临时表名称以单个哈希(“#”)符号开头。

CREATE TABLE #LocalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into #LocalTemp values ( 1, 'Name','Address');
GO
Select * from #LocalTemp

本地临时表的范围存在于当前用户的当前会话意味着当前查询窗口。如果您将关闭当前查询窗口或打开一个新的查询窗口,并尝试在上面创建的临时表中查找,则会出现错误。


2.) 全局临时表永久保留在数据库中,但是行仅存在于给定的连接中。关闭连接后,全局临时表中的数据消失。但是,表定义保留在数据库中,以便下次打开数据库时进行访问。

全局临时表可用于所有SQL Server会话或连接(意味着所有用户)。这些可以由任何SQL Server连接用户创建,并且在所有SQL Server连接都关闭后会自动将其删除。全局临时表名称以双哈希(“ ##”)符号开头。

CREATE TABLE ##GlobalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into ##GlobalTemp values ( 1, 'Name','Address');
GO
Select * from ##GlobalTemp

全局临时表对所有SQL Server连接可见,而本地临时表仅对当前SQL Server连接可见。


2
您对全局临时表的定义是我希望它的行为方式(来自其他数据库),但是我的测试表明,SQL Server中实际发生的情况是:“创建该表的会话会自动删除全局临时表结束,所有其他任务均已停止引用它们”
Nickolay

11

在线丛书中的报价:

本地临时表仅在当前会话中可见;全局临时表对所有会话可见。

临时表超出范围时会自动删除,除非使用DROP TABLE明确删除了它们:

  • 存储过程完成后,将自动删除在存储过程中创建的本地临时表。该表可以由创建表的存储过程执行的任何嵌套存储过程引用。调用创建该表的存储过程的进程无法引用该表。
  • 所有其他本地临时表将在当前会话结束时自动删除。
  • 当创建临时表的会话结束并且所有其他任务停止引用它们时,全局临时表将自动删除。任务和表之间的关联仅在单个Transact-SQL语句的生命周期内维护。这意味着在创建会话结束时,最后一个正在主动引用该表的Transact-SQL语句完成时,将删除全局临时表。

0

本地临时表:如果创建本地临时表,然后打开另一个连接并尝试查询,则会收到以下错误。

临时表只能在创建它们的会话中访问。

全局临时表:有时,您可能想创建一个可通过其他连接访问的临时表。在这种情况下,您可以使用全局临时表。

仅当所有引用临时表的会话关闭时,才会销毁全局临时表。


0

值得一提的是:数据库范围的全局临时表(当前仅由Azure SQL数据库支持)。

SQL Server的全局临时表(以##表名开头)存储在tempdb和 在整个SQL Server实例的所有用户会话之间共享。

Azure SQL数据库支持全局临时表,这些临时表也存储在tempdb中,范围为数据库级别。这意味着全局临时表在同一Azure SQL数据库中为所有用户会话共享。来自其他数据库的用户会话无法访问全局临时表。

-- Session A creates a global temp table ##test in Azure SQL Database testdb1
-- and adds 1 row
CREATE TABLE ##test ( a int, b int);
INSERT INTO ##test values (1,1);

-- Session B connects to Azure SQL Database testdb1 
-- and can access table ##test created by session A
SELECT * FROM ##test
---Results
1,1

-- Session C connects to another database in Azure SQL Database testdb2 
-- and wants to access ##test created in testdb1.
-- This select fails due to the database scope for the global temp tables 
SELECT * FROM ##test
---Results
Msg 208, Level 16, State 0, Line 1
Invalid object name '##test'

更改数据库范围的配置

GLOBAL_TEMPORARY_TABLE_AUTODROP = { ON | OFF }

适用于:Azure SQL数据库(功能已在公共预览版中)

允许设置全局临时表的自动删除功能。缺省值为ON,这意味着在任何会话不使用全局临时表时,它们都会自动删除。设置为OFF时,需要使用DROP TABLE语句显式删除全局临时表,或者在服务器重新启动时将其自动删除。

使用Azure SQL数据库单个数据库和弹性池,可以在SQL数据库服务器的各个用户数据库中设置此选项。在SQL Server和Azure SQL数据库托管实例中,此选项在TempDB中设置,单个用户数据库的设置无效。


0

我没有看到任何答案向用户显示可以在哪里找到Global Temp表。在SSMS中导航时,可以在同一位置查看本地和全局临时表。下面的截图来自此链接

数据库->系统数据库-> tempdb->临时表

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.