CTE 和 TEMP 表之间的主要区别是啥?
Posted
技术标签:
【中文标题】CTE 和 TEMP 表之间的主要区别是啥?【英文标题】:What are the Main difference between CTE's and TEMP tables?CTE 和 TEMP 表之间的主要区别是什么? 【发布时间】:2013-08-31 18:54:30 【问题描述】:使用CTE's
(common table expressions
) 代替temp tables
有什么好处。
我在它们之间进行了性能测试,但我找不到它们之间的太大差异。
使用CTE'S
有哪些优缺点?
【问题讨论】:
来自 DBA 站点 What's the difference between a CTE and a Temp Table? 我不太了解性能差异,但是 cte 允许简单的循环和递归,如果查询输出将被多次访问并且重新运行将浪费时间。 它们是不同的东西,真的是课程的马。哪个最好取决于您的具体情况。你的问题不亚于What are the benefits of using Views rather than tables?
CTE 的执行速度也较慢,因为结果未缓存。因此,每次您使用 CTE 时,它都会重新运行查询、计划和所有操作
^ 这很重要,尤其是在 CTE/TT 处理数百万行数据的情况下。
【参考方案1】:
CTE 和临时表之间的最大区别可能在于,CTE 的执行范围是单个 SELECT、INSERT、UPDATE、DELETE 或CREATE VIEW 语句。
基本上你不能像使用临时表一样重用 CTE。
来自documentation
公用表表达式 (CTE) 可以被认为是临时的 在单个的执行范围内定义的结果集 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句。 CTE 是 类似于派生表,因为它不存储为对象,并且 仅在查询期间持续。与派生表不同,一个 CTE 可以是自引用的,并且可以在 相同的查询。
CTE 可用于:
创建递归查询。有关详细信息,请参阅使用公用表表达式的递归查询。
在不需要一般使用视图时替换视图;也就是说,您不必将定义存储在元数据中。
启用按从标量子选择派生的列或不确定或具有外部访问权限的函数进行分组。
在同一语句中多次引用结果表。
【讨论】:
对我来说最大的不同是一个是实际的表,另一个不是。WITH CTE AS (SELECT * FROM MillionRowTable) SELECT TOP 1 * FROM CTE
和INSERT INTO #T SELECT * FROM MillionRowTable; SELECT TOP 1 * FROM #T
有很大区别
@MartinSmith 你的评论比答案本身有更多的投票!!
反之亦然:insert into #table
后跟 select .. where xyz not in #table
很快,但重写为 CTE 会非常慢。【参考方案2】:
CTE : CTE 代表公用表表达式。它是在 SQL Server 2005 中引入的。它用于在临时基础上存储复杂子查询的结果。它的寿命仅限于当前查询。它是使用 WITH 语句定义的。主要用于递归调用。
示例
;with myCTE as
(
select ParentLevel, ParentID, ChildID
from MHA
where ChildID = 1
UNION ALL
select MHA.ParentLevel, MHA.ParentID, MHA.ChildID
from MHA
inner join myCTE on MHA.ParentID = myCTE.ChildID
where MHA.ParentID <> 0
)
(错误)
select top (5) * from myCTE
所以在上面的例子中,我创建了 CTE 名称为 myCTE ,只能在上面的查询中使用(我不能在上面的查询之外使用 myCTE)
TEMP:它也用于临时存储查询结果。但它的寿命仅限于当前会话。它是使用# 定义的。它不支持递归。
示例:
select * into #tempTable from MHA
在上面的查询中,我创建了临时表,现在我可以在此查询之外使用临时表,但在会话中。见下文
(无错误)
select top (5) * from #tempTable
【讨论】:
以上是关于CTE 和 TEMP 表之间的主要区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章