两个不同的 INSERT INTO 语句做同样的事情

Posted

技术标签:

【中文标题】两个不同的 INSERT INTO 语句做同样的事情【英文标题】:Two different INSERT INTO statements that do the same thing 【发布时间】:2012-08-16 07:33:33 【问题描述】:

我正在深入研究大量使用 SQL(使用 Oracle 11g)的遗留代码(C++/Qt)。我已经附带了这段代码(只是更改了变量名称并将其写入多行以获得更好的可读性):

insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) select 
999, 
D.FIRST, 
(select O.SECOND from TABLE_TWO O where O.ID=555), 
333, 
444 
from TABLE_ONE D where D.ID=666

格式为 INSERT INTO ... SELECT ...

现在看来这里 "select" 与 insert 一起使用以检索并创建具有单行的行。但是语法似乎很尴尬。我把它改成:

insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) values (
999, 
(select D.FIRST from TABLE_ONE D where D.ID=666), 
(select O.SECOND from TABLE_TWO O where O.ID=555), 
333, 
444) 

而且这个工作没有任何问题。格式为 INSERT INTO ... VALUES ...

在性能或其他方面有什么不同吗?因为第二行对我来说似乎更自然。

【问题讨论】:

第一个示例允许您一次插入多于 1 行,这在您的情况下并不重要,但您可以根据 WHERE 条件插入多于一行。第二个例子只插入一行。 【参考方案1】:

区别在于结果集的基数。

无论 TABLE_ONE 中有多少行匹配D.ID=666,第一条语句都将起作用。而如果返回多于一行,则第二个语句将失败。

为了完整起见,还有第三种变体:

insert into FOO_TABLE (BEGIN, FIRST_VALUE, SECOND_VALUE, VALUE, BAR) select  
999,  
D.FIRST,  
O.SECOND,  
333,  
444  
from TABLE_ONE D 
    cross join TABLE_TWO  O
where O.ID=555
and D.ID=666   

Oracle 优化器足够聪明,可以知道 TABLE_TWO 是否匹配唯一键,并据此制定执行计划。


关于相对性能,所有变化都应该是相同的。当然,如果两个查询都返回一行,这就是我所期望的。如果 TABLE_ONE 返回多行,则可能存在差异。与往常一样,在调整查询时,您必须对每种方法进行基准测试,因为执行时间对数据量和偏差很敏感。

【讨论】:

哪一款性能最好?我的意思是哪种方法最好,您的解决方案也是可读的,但我知道 3 个选项:)

以上是关于两个不同的 INSERT INTO 语句做同样的事情的主要内容,如果未能解决你的问题,请参考以下文章

如何将sqlserver表中的数据导出sql语句或生成insert into语句

insert into 语句出现错误,不知应该怎么将参数传入数据库?

sql insert into语句错误

自增列和insert into的问题

“INSERT INTO 语句中的语法错误”和“没有为一个或多个必需参数提供值”

sql语句 两个表字段不一致 如何将表2内容insert into表1中