2012-08-16 88 views
0

我正在深入使用SQL(使用Oracle 11g)的遗留代码(C++/Qt)。我来到这片代码(只是多行更改的变量名和写一个更好的可读性):两个不同的INSERT INTO语句做同样的事情

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 ...

形式现在看来这里“选择”与插入一起使用来检索并创建一行单行。但是,语法看起来很尴尬。我将它改为:

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 ...

在表现或任何其他方面是否有任何区别?因为第二行对我来说似乎更自然。

+0

第一个示例允许您一次插入多于1行,在您的情况下这不会影响,但您可以根据WHERE条件插入多于一行的内容。第二个示例只插入一行。 – 2012-08-16 07:36:57

回答

2

不同之处在于结果集的基数。

无论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返回多行,可能会有差异。与往常一样,当调整查询时,您必须对每种方法进行基准测试,因为执行时间对数据量和偏差敏感。

+0

哪一个是性能最好的?我的意思是哪种方法是最好的,你的解决方案也是可读的,但在那里我知道3个选项:) – 2012-08-16 10:33:19