MSSQL中CTE,临时表和表变量的区别

Noo*_*uvo 7 sql sql-server performance temp-tables common-table-expression

所有都用于临时存储数据.

这3种临时表是否存在性能差异(时间复杂度和空间复杂度)?

性能问题应取决于结果是保存在磁盘还是内存中.

我搜索了很多,但没有得到满意的答案.

raj*_*dav 4

CTE - 公共表表达式 CTE 代表公共表表达式。它是在 SQL Server 2005 中引入的。它是一个临时结果集,通常可能是复杂子查询的结果。与临时表不同,它的生命周期仅限于当前查询。它是通过使用WITH语句来定义的。CTE 提高了复杂查询和子查询的可读性和易于维护性。CTE 始终以分号开头。

With CTE1(Address, Name, Age)--Column names for CTE, which are optional
AS
(
SELECT Addr.Address, Emp.Name, Emp.Age from Address Addr
INNER JOIN EMP Emp ON Emp.EID = Addr.EID
)
SELECT * FROM CTE1 --Using CTE 
WHERE CTE1.Age > 50
ORDER BY CTE1.NAME
Run Code Online (Sandbox Code Playgroud)

何时使用 CTE?这用于存储复杂子查询的结果以供进一步使用。

这也用于创建递归查询。

临时表 在 SQL Server 中,临时表是在运行时创建的,您可以执行对普通表可以执行的所有操作。这些表是在 Tempdb 数据库内创建的。根据范围和行为,临时表有两种类型,如下所示:

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

CREATE TABLE #LocalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into #LocalTemp values ( 1, 'Shailendra','Noida');
GO
Select * from #LocalTemp
Run Code Online (Sandbox Code Playgroud)

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

全局临时表 全局临时表可供所有 SQL Server 会话或连接(指所有用户)使用。这些可以由任何 SQL Server 连接用户创建,并且当所有 SQL Server 连接关闭时它们会自动删除。全局临时表名称以双井号(“##”)开头。

CREATE TABLE ##GlobalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into ##GlobalTemp values ( 1, 'Shailendra','Noida');
GO
Select * from ##GlobalTemp
Run Code Online (Sandbox Code Playgroud)

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

表变量 它的作用类似于变量,存在于特定批次的查询执行中。一旦脱离批次,它就会被丢弃。这也是在 Tempdb 数据库中创建的,但不是在内存中创建的。这还允许您在表变量声明时创建主键、标识,但不能创建非聚集索引。

 GO
 DECLARE @TProduct TABLE
 (
 SNo INT IDENTITY(1,1),
 ProductID INT,
 Qty INT
 ) 
 --Insert data to Table variable @Product 
 INSERT INTO @TProduct(ProductID,Qty)
 SELECT DISTINCT ProductID, Qty FROM ProductsSales ORDER BY ProductID ASC 
 --Select data
 Select * from @TProduct

 --Next batch
 GO
 Select * from @TProduct --gives error in next batch
Run Code Online (Sandbox Code Playgroud)

注意 临时表是在 Tempdb 数据库中物理创建的。这些表充当普通表,并且也可以像普通表一样具有约束、索引。

CTE 是一个命名的临时结果集,用于操作复杂的子查询数据。这是针对声明范围而存在的。这是在内存中而不是 Tempdb 数据库中创建的。您无法在 CTE 上创建任何索引。

表变量的作用类似于变量,存在于特定批次的查询执行中。一旦脱离批次,它就会被丢弃。这也是在 Tempdb 数据库中创建的,但不是在内存中创建的。