SELECT INTO vs WITH AS:临时表方法谁更快?

Posted

技术标签:

【中文标题】SELECT INTO vs WITH AS:临时表方法谁更快?【英文标题】:SELECT INTO vs WITH AS: Who is faster in the temp table approach? 【发布时间】:2021-04-05 15:18:39 【问题描述】:

我对这两种结构有一点经验。使用一个或另一个使用临时表是否会提高性能?

我知道SELECT INTO 创建了一个在查询后仍然存在并在一段时间后被删除的表。几秒钟后使用相同的查询时会出现一些问题(SQL 错误 [2714] [S0001]:数据库中已经有一个名为#XXXXX 的对象)。因此,如果您以不同的方法使用该临时表进行大量查询,则无需再次创建该表。这是一个可以由不同用户使用的表,包括在内。 WITH AS 只需在当前查询中创建临时表,然后立即删除。

我没有更多信息。

【问题讨论】:

"WITH AS 只是在当前查询中创建临时表,然后立即删除。" WITH 不创建临时表;那将是CREATE TABLE #TempTableName (Columns List) 【参考方案1】:

你混淆了两个概念。

SELECT INTO 创建一个新表。那可以是临时表或永久表。但是 table 已创建。

WITH 定义了在单个查询中使用的通用表表达式 (CTE)。这不是一张“桌子”。它只是一个子查询,它可能会也可能不会具体化为临时表(实际上,SQL Server 通常不会具体化 CTE)。

当你想要一张真正的桌子时,你可以使用SELECT INTO。一些原因是:

在多个查询之间共享数据。 收集正确的统计信息以帮助查询优化器。 添加索引以提高后续查询性能。

当您想要在查询中使用命名子查询时,您可以使用 CTE。如果您在两者之间进行选择,您可能希望从 CTE 开始。

【讨论】:

感谢您的帮助!如果 CTE 没有具体化,那么对于每个 CTE 调用是否一直运行相同的查询?我只是担心查询搜索的许多执行而不是放在缓存/临时表中。 @HelioJunior 。 . .代码运行多少次取决于优化器。 SQL Server 倾向于在每次引用代码时重新运行代码。【参考方案2】:

天哪,我该从哪里开始?

首先,请参阅:

What are the Main difference between CTE's and TEMP tables?

这两者之间有很大的不同。

Temp 和 Global Temp 表

可以索引 坚持过去创建它们的语句 为当前会话保存在 tempdb 中

CTE 的

临时结果集

可用于递归

范围是声明

现在让我们谈谈一些轶事,或者你会看到的常见事情:

他们说使用临时表进行表查询已针对批量插入性能进行了优化,尽管我想我记得在 SQL Server 2019 中已经不再是这种情况了,但我还没有看到支持这一点的证据。话虽如此,它是一种实时复制表结构的真正方便的方法,因此您会在很多地方看到这种技术。

另一种常见的临时表技术用于预过滤结果集,而不是尝试将连接左侧的大表与右侧的另一个较大表连接起来。这会导致大量读取,并且通常将您需要的切片从第一个表中取出到临时表中,以通过规避该行为来获得性能。同样,这很常见,在使用 JOINS 和更大的表时应该习惯于考虑这一点。

使用一系列 CTE 进行 JOINS - 我见过很多,但总是很糟糕。在最终选择查询中连接多个 CTE 所需的所有哈希表和循环最终会导致性能下降。它总是以大量不必要的读取而告终。

对于它的价值,大多数时候使用 CTE,除非您将它们用于递归逻辑或构建快速/简单的笛卡尔积(或其他易于构建的列表),我几乎总是重写它们以支持的其他技术。这也不一定是个人风格的事情,我只是认为在正常情况下索引临时表和表变量的能力是有价值的。而且总体上发生的读取次数通常较少。这里的想法是确保您分析这两种方法并选择总体上最好的一种。

【讨论】:

非常感谢朋友

以上是关于SELECT INTO vs WITH AS:临时表方法谁更快?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE WITH AS 用法,创建临时表

ORACLE创建临时事务表global temporary table 和 查询时临时表with tempName as (select ) select

oracle with as 用法

oracle--with as

with as的用法

关于oracle with as用法