2

私はオラクル11gを使用しています。

関連するテーブルが 2 つあります。格納された値 (A) と挿入する新しい値 (B) です。どちらも 3 つの列 (クライアント、グループ、個人コード) の ID で関連付けられています。各テーブルには、他に約 20 の列があります (属性と呼びましょう)。

どの値が新しいか (ID は B にあり、ID は A にはない) を知ることができるように、それらを一致させる必要があるため、それらを A に挿入します。新しい値 (ID は A にありますが、B にはありません) であるため、保存されている値 (A) からそれらを削除します。

例えば:

A:

クライアント | グループ | 個人コード | 名前 | 姓
_________________________________________________
1 | 1 | 1 | ジョー | ジョー | 雌
1 | 1 | 2 | カール | ジョン
1 | 1 | 3 | ジョン | ジョン

B:

クライアント | グループ | 個人コード | 名前 | 姓
_________________________________________________
1 | 1 | 1 | ジョー | ジョー | 雌
1 | 1 | 3 | ジョン | ジョン
1 | 1 | 4 | メアリー | 詐欺

この例では、人物 4 は新規で、人物 2 は削除する必要があり、1 と 3 は同じままです。

したがって、次の結果を返すクエリが必要です。

クライアント | グループ | 個人コード | アクション
_________________________________________
1 | 1 | 1 | 同等
1 | 1 | 2 | 削除する
1 | 1 | 3 | 同等
1 | 1 | 4 | 新着

私が作成したのは、次のクエリです。

   WITH 
   A AS (
    -- select from A table
   ), 
   B AS
   (
       -- select from B table
   ),     
   delete AS 
   (
    -- select from A WHERE NOT EXISTS (B.id = A.ID)
   ),       
   news AS 
   (
    -- select from B WHERE NOT EXISTS (A.id = B.ID)
   ),
   eq AS 
   (
    -- select A.* from A, B WHERE A.id = B.id AND A.attributes = B.attributes
   ) 
   select action.client, action.group, action.personcode, 'remove' from delete action
   UNION ALL
   select action.client, action.group, action.personcode, 'new' from news action
   UNION ALL
   select action.client, action.group, action.personcode, 'equal' from eq action
   ;

問題は、これらの 3 つの lasts select はそれぞれ 10 秒未満で実行されますが、 UNIONorを使用してそれらをマージするUNION ALLと、delete または new または equal が空であっても、完全なクエリが約 90 秒続くことです。A または B で 3000 行を超える可能性があります。

この結果をより良く、より速く取得する方法はありますか?

4

3 に答える 3

4

テーブルを外部結合して、テーブル間の違いのログを生成できます。

select coalesce(a.id,b.id) id,
       case when a.id is null
              then 'new'
            when b.id is null
              then 'remove'
            when a.col1 = b.col1 and a.col2 = b.col2 ...
              then 'same'
            else 'different'
        end
from    a full outer join b on (a.id = b.id)
于 2012-12-13T12:49:01.970 に答える
2

テーブル B に必要なデータがある場合、テーブル A の代わりにそのテーブルを使用しないのはなぜですか? 正しいデータを含むシノニムを指すシノニムを作成し、それを参照します。

于 2012-12-13T11:42:11.733 に答える
0

では、皆様お返事ありがとうございます。このブログで説明されている戦略を使用して、最初の 2 つのクエリをフィルター処理するためのパラメーターを渡すビューを最終的に作成しました。 現在、完全なプロセスは 30 秒続き、A または B に行がない場合は 0 です (以前は、常に 90 秒続きます)。これは、現在の手順への影響が少ないソリューションです。

于 2012-12-14T12:31:33.530 に答える