2016-12-07 9 views
0

現時点ではEnterpriseなしでOracle 11gを使用しています(残念なことにオプションではありません)。Oracleベースの挿入とセットベースのマージ・パフォーマンス

たとえば、データの行が一定の(つまり、2000としましょう)テーブルがあります。それをdata_sourceと呼ぶことにしよう。

このテーブルのいくつかのカラムを別のテーブルdata_destに挿入したいとします。私は、ソーステーブルからすべてのレコードを使用しています。言い換えれば

、私はこれが、この場合には速いだろう

select data_source.col1, data_source.col2, ... data_source.colN 
from data_source 

設定を挿入したいと思います:

insert into data_dest 
    select data_source.col1, data_source.col2, ... data_source.colN 
    from data_source 

OR

merge into data_dest dd 
    using data_source ds 
    on (dd.col1 = ds.col1) --Let's assume that this is a matching column names 
    when not matched 
    insert (col1,col2...) 
    values(ds.col1,ds.col2...)  

EDIT 1: を我々インサートからの主キー違反がないとみなすことができます。 つまり、insertによってすべての行が正常に挿入されるため、マージすることができます。

+1

'EXPLAIN PLAN FOR the_first_query_insert'、次に' SELECT * FROM table(DBMS_XPLAN.Display) 'を実行してください。 ** 2番目のクエリ**の結果をビットマップではなくテキストとしてコピーする** - 単純な "コピーペースト"を使用して質問に追加する。次に、2番目のクエリのための上記の手順を繰り返します。 ''第2_query_merge'のためのEXPLAIN PLANなど – krokodilko

+0

@krokodilkoええインサートは速くなるようです。 –

+0

@krokodilkoこれは素晴らしいチューニングテクニックです。 –

答えて

1

insertは、2つのテーブルの結合を必要としないため、非常に高速です。

つまり、2つのクエリは同等ではありません。 col1がプライマリキーとして定義されていると仮定すると、はdata_sourceの値がcol1で、すでにdata_destにある場合、エラーをスローします。 mergeは2つのテーブルのデータを比較しており、まだ存在していない行だけを挿入するため、主キー違反は発生しません。

mergeに相当しますinsertは次のようになります。

INSERT INTO data_dest 
    SELECT data_source.col1, data_source.col2, ... data_source.colN 
    FROM data_source 
    WHERE NOT EXISTS 
      (SELECT * 
       FROM data_dest 
       WHERE data_source.col1 = data_dest.col1) 

それはこのinsertための計画がmergeための計画に(同一でない場合は)非常に似ていますし、パフォーマンスがあろうと考えられます区別できない。

+0

ありがとうございます、我々はデータが繰り返されていないと仮定することができます。 –

+1

その場合、 'merge'の使用には何の意味もありません。それは、(エンジンが挿入されているデータが一意でないことをエンジンが知らないので)比較を実行します。これはリソースの無駄です。 – Allan

関連する問題