插入INTO与SELECT INTO

jow*_*ece 121 t-sql sql-server sql-server-2008

使用之间有什么区别

SELECT ... INTO MyTable FROM...
Run Code Online (Sandbox Code Playgroud)

INSERT INTO MyTable (...)
SELECT ... FROM ....
Run Code Online (Sandbox Code Playgroud)

从BOL [ INSERT,SELECT ... INTO ],我知道使用SELECT ... INTO将在默认文件组上创建插入表(如果它尚不存在),并且此语句的日志记录取决于恢复数据库的模型.

  1. 哪种说法更可取?
  2. 还有其他性能影响吗?
  3. SELECT ... INTO over INSERT INTO ...的一个很好的用例是什么?

编辑:我已经声明我知道SELECT INTO ...创建一个不存在的表.我想知道的是SQL包含这个语句是有原因的,它是什么?它是在幕后插入行做的不同的事情,还是只是在a CREATE TABLEINSERT INTO.之上的语法糖.

JNK*_*JNK 116

  1. 他们做不同的事情.INSERT表存在时使用.SELECT INTO当它没有时使用.

  2. 是. INSERT通常不记录表提示. SELECT INTO假设设置了适当的跟踪标志,则记录最少.

  3. 根据我的经验SELECT INTO,最常用于中间数据集,如#temp表格,或复制整个表格,如备份. INSERT INTO在插入具有已知结构的现有表时使用.

编辑

为了解决您的编辑,他们会做不同的事情.如果你正在制作一个表并想要定义结构使用CREATE TABLEINSERT.可以创建的问题示例:您有一个带有varchar字段的小表.表中最大的字符串现在是12个字节.您的实际数据集最多需要200个字节.如果SELECT INTO您从小表中创建一个新表,后者INSERT将因截断错误而失败,因为您的字段太小.

  • 我的两分钱,我认为引入失败是一件好事.我想知道我的数据是否与我预期的数据格式/大小不符.我总是尝试使用`CREATE TABLE`然后`INSERT INTO'来定义我的表.此外,更容易测试`SELECT`语句本身,而不执行插入. (3认同)
  • @Jowenece - 是的,我希望如此。如果我要遇到那个麻烦,我将继续使用`CREATE`语句。 (2认同)

HLG*_*GEM 21

  1. 哪种说法更可取? 取决于你在做什么.

  2. 还有其他性能影响吗?如果表是永久表,则可以在创建表时创建索引,这会对性能产生负面影响和积极影响.Select into不会重新创建当前表中存在的索引,因此后续使用该表可能比它需要的速度慢.

  3. SELECT ... INTO over INSERT INTO ...的一个很好的用例是什么?如果您可能事先不知道表结构,则使用Select into.写入比创建表和插入语句更快,因此它有时用于加速开发.当您创建快速临时表来测试事物或特定查询的备份表(可能是要删除的记录)时,通常会更快地使用它.很少见到它会在生产代码中使用多次运行(临时表除外),因为如果表已经存在,它将失败.

有时候,那些不知道自己在做什么的人会不恰当地使用它.因此,它们会导致数据库中的混乱.我强烈认为将SELECT INTO用于除了一次性表(临时备份,将在存储过程结束时消失的临时表等)以外的任何内容都是不合适的.永久表需要对其设计进行真正的考虑,SELECT INTO使得很容易避免考虑任何事情,即使是基本的列和什么数据类型.

一般来说,我更喜欢使用create table和insert语句 - 你有更多的控件,它对于可重复的进程更好.此外,如果表是永久表,则应该从单独的创建表脚本(源代码控制中的脚本)创建它,因为创建永久对象通常不应该在代码中插入/删除/更新或从中选择表.对象更改应与数据更改分开处理,因为对象具有超出特定插入/更新/选择/删除需要的含义.您需要考虑最佳数据类型,考虑FK约束,PK和其他约束,考虑审计要求,考虑索引等.


Joe*_*lli 7

每个语句都有一个不同的用例。它们不可互换。

SELECT...INTO MyTable...MyTable在以前不存在的地方创建一个新的。

INSERT INTO MyTable...SELECT...MyTable已存在时使用。

  • 你的问题的答案是隐含的。为了更清楚,没有“首选”语句,因为每个语句都有不同的用例。声明不可互换。当您要创建一个不存在的新表时,请使用第一个版本。当表已经存在时使用第二个版本。 (6认同)
  • 你没有回答我的任何问题,我已经说明了你的答案。 (5认同)
  • 为什么我要这样做而不是创建一个临时表然后插入它?有优势吗? (2认同)

rsb*_*rro 5

主要区别在于SELECT INTO MyTable将创建一个名为MyTable的新表,其中包含结果,而INSERT INTO则要求MyTable已存在.

只有在表不存在且您希望根据查询结果创建表时,才会使用SELECT INTO.因此,这两个陈述确实无法比较.他们做了很多不同的事情.

通常,SELECT INTO更常用于一个关闭任务,而INSERT INTO经常用于向表添加行.

编辑:
虽然您可以使用CREATE TABLE和INSERT INTO来完成SELECT INTO所做的事情,但使用SELECT INTO您不必事先知道表定义.SELECT INTO可能包含在SQL中,因为它使得临时报告或复制表等任务变得更加容易.


AJC*_*AJC 5

实际上SELECT ... INTO不仅创建表,而且如果它已经存在就会失败,所以基本上你唯一一次使用它是当你插入的表不存在时。

关于您的编辑:

我个人在创建临时表时主要使用SELECT ... INTO。这对我来说是主要用途。但是,我在创建具有许多与其他表结构相似的列的新表时也会使用它,然后对其进行编辑以节省时间。

  • @jowenece 我认为主要是为了简单......还说你有一个动态查询。我你不知道结构,你不能事先创建表,使用 SELECT... INTO 比动态创建表要容易得多。 (3认同)

Nir*_*raj 5

我只想讨论与性能相关的问题的第二点,因为没有其他人讨论过这一点。当涉及到具有大型数据集的表时,选择插入比插入要快得多。当我必须读取一个非常大的表时,我更喜欢 select into 。对于一个有 1000 万行的表,insert into 可能需要几个小时,而 select into 会在几分钟内完成,至于新表上丢失索引,您可以通过查询重新创建索引,与插入。

  • 确实如此,但这主要是因为 SQL Server 知道不存在对目标表的争用。`insert into #temp with(tablock) select * from ..` 的性能与 `select * into #temp from ...` 的性能大致相同 (2认同)