0

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

性能やその他の点で違いはありますか?2行目の方が自然に見えるからです。

4

1 に答える 1

2

違いは、結果セットのカーディナリティです。

最初のステートメントは、TABLE_ONE の一致する行数に関係なく機能しますD.ID=666。一方、複数の行が返される場合、2 番目のステートメントは失敗します。

完全を期すために、3 番目のバリエーションがあります。

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 が複数の行を返す場合、違いがある可能性があります。いつものように、クエリのチューニングに関しては、実行時間はデータ量とスキューの影響を受けるため、各アプローチをベンチマークする必要があります。

于 2012-08-16T07:45:40.983 に答える