插入INTO与SELECT INTO

时间:2011-08-04 20:16:07

标签: sql-server tsql sql-server-2008

使用

之间有什么区别
SELECT ... INTO MyTable FROM...

INSERT INTO MyTable (...)
SELECT ... FROM ....

从BOL [INSERTSELECT...INTO],我知道使用SELECT ... INTO会在默认文件组上创建插入表已经存在,并且此语句的日志记录取决于数据库的恢复模型。

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

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

11 个答案:

答案 0 :(得分:111)

  1. 他们做不同的事情。当表存在时使用INSERT。如果没有,请使用SELECT INTO

  2. 是。通常记录没有表提示的INSERT。假设设置了正确的跟踪标志,则SELECT INTO被最小化记录。

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

  4. 修改

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

答案 1 :(得分:20)

  1. 哪种陈述更可取?取决于您的工作。

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

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

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

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

答案 2 :(得分: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中,因为它使得临时报告或复制表等任务变得更加容易。

答案 3 :(得分:4)

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

SELECT...INTO MyTable...创建一个新的MyTable,其中之前不存在。

<{1}}已经存在时使用

INSERT INTO MyTable...SELECT...

答案 4 :(得分:4)

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

关于你的编辑:

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

答案 5 :(得分:2)

SELECT INTO通常用于生成临时表或复制另一个表(数据和/或结构)。

在日常代码中,您使用INSERT,因为您的表应该已经存在,可以读取,UPDATEd,DELETEd,JOINed等。注意:INTO关键字对于INSERT是可选的

也就是说,应用程序通常不会创建和删除表作为正常操作的一部分,除非它是一个临时表,用于某些范围限制和特定用途。

SELECT INTO创建的表将没有键或索引或约束,这与真实的,持久的,已存在的表不同

2不能直接比较,因为它们在使用中几乎没有重叠

答案 6 :(得分:1)

我只想涵盖与表现有关的问题的第二点,因为其他人没有涵盖这一点。当涉及具有大型数据集的表时,选择Into比插入更快。当我必须阅读一张非常大的桌子时,我更喜欢选择。插入一个包含1000万行的表可能需要几个小时,而select into会在几分钟内执行此操作,而对于新表上的丢失索引而言,您可以通过查询重新创建索引,并且与以下相比可以节省更多时间插入。

答案 7 :(得分:0)

Select into为您创建新表,然后从源表中插入记录。新创建的表具有与源表相同的结构。如果您尝试对现有表使用select into,则会产生错误,因为它将尝试创建具有相同名称的新表。 Insert into要求在您的数据库中插入行之前存在该表。

答案 8 :(得分:0)

select Into和Insert Into之间的简单区别是: - &GT;选择不需要现有表格。如果要复制表A数据,只需从A键入Select * INTO [tablename]。这里,tablename可以是现有表,也可以创建新表,其结构与表A相同。

- &GT; Insert Into确实需要现有的table.INSERT INTO [tablename] SELECT * FROM A;。 这里tablename是一个现有的表。

Select Into通常更受欢迎,可以复制数据,尤其是备份数据。

您可以根据您的要求使用,它完全是开发人员的选择,应该在他的场景中使用。

性能方面插入INTO很快。

参考文献:

https://www.w3schools.com/sql/sql_insert_into_select.asp https://www.w3schools.com/sql/sql_select_into.asp

答案 9 :(得分:0)

其他答案都很好/正确(主要区别在于 DestTable 是否已经存在 (INSERT) 或尚不存在 (SELECT ... INTO))

您可能更喜欢使用 INSERT(而不是 SELECT ... INTO),如果您希望能够COUNT(*) 目前已插入的行。

使用 SELECT COUNT(*) ... WITH NOLOCK 是一种简单/粗略的技术,可以帮助您检查 INSERT 的“进度”;如果是长时间运行的插入,则很有帮助,as seen in this answer)。

<块引用>

[如果你使用...] INSERT DestTable SELECT ... FROM SrcTable ...那么您的 SELECT COUNT(*) from DestTable WITH (NOLOCK) 查询将起作用。

答案 10 :(得分:-2)

对大型数据集的选择可能仅适用于使用与数据库执行批量操作任务的单个连接的单个用户。我不建议使用

SELECT * INTO table

因为这会创建一个大事务并创建模式锁以创建对象,从而阻止其他用户创建对象或访问系统对象,直到SELECT INTO操作完成。

作为概念证明打开2个会话,在第一个会话中尝试使用

select into temp table from a huge table 

并在第二部分尝试

create a temp table 

并检查锁定,阻塞和第二个会话的持续时间以创建临时表对象。我的建议是创建和插入语句总是一个好习惯,如果需要最小日志记录使用跟踪标志610.