0

40以上の同じ構造のデータベースを1つの統合データベースに統合するプロセスがありますが、唯一の違いは、統合データベースが各テーブルにproject_idフィールドを追加することです。

可能な限り効率的にするために、レコードが追加/変更された場合にのみ、ソースデータベースから統合データベースにレコードをコピー/更新しようとしています。統合データベースから古いレコードを削除してから、存在しないレコードをコピーします。古い/変更されたレコードを削除するには、次のようなクエリを使用しています。

DELETE FROM <table> 
 WHERE NOT EXISTS (SELECT <primary keys> 
                     FROM <source> b 
                    WHERE ((<b.fields = a.fields>) or 
                          (b.fields is null and a.fields is null))) 
  AND PROJECT_ID = <project_id>

これはほとんどの部分で機能しますが、ソースデータベースのテーブルの1つに700,000を超えるレコードがあり、このクエリが完了するまでに1時間以上かかります。

このクエリをより効率的にするにはどうすればよいですか?

4

4 に答える 4

2

タイムスタンプ以上の監査テーブルを使用して、時刻「X」以降に変更されたレコードを識別し、最後の同期が開始されたときの時刻「X」を節約します。これをインターフェースフィードに使用します。

于 2009-10-05T18:45:15.557 に答える
0

WHEREステートメントを並べ替えることができます。4つの比較があり、失敗する可能性が最も高いものを最初に配置します。

データベース/アプリケーションをわずかに変更でき、これを再度行う必要がある場合は、「更新済み」というビットフィールドは悪い追加ではない可能性があります。

于 2009-10-05T19:08:32.547 に答える
0

NULLフィルターを使用してLEFTJOINを試してみてください。

DELETE      <table> 
FROM        <table> t
LEFT JOIN   <source> b 
        ON (t.Field1 = b.Field1 OR (t.Field1 IS NULL AND b.Field1 IS NULL))
        AND(t.Field2 = b.Field2 OR (t.Field2 IS NULL AND b.Field2 IS NULL))
        --//...
WHERE       t.PROJECT_ID = <project_id>
        AND b.PrimaryKey IS NULL --// any of the PK fields will do, but I really hope you do not use composite PKs

ただし、PK以外のすべての列を比較している場合は、クエリに問題が発生します。

この場合、AFTERUPDATEトリガーで更新できるUpdatedAtTIMESTAMPフィールド(DVKが提案するように)を両方のデータベースに追加することをお勧めします。PKとUpdatedAt列を含むインデックスを作成すると、同期手順がはるかに高速になります。 。

于 2009-10-05T19:00:25.870 に答える
0

私は通常、このようなクエリを書き直して、not ... Not Inを回避しますが、Not Existsはこれを改善しますが、パフォーマンスはひどいものです。

この記事、http://www.sql-server-pro.com/sql-where-clause-optimization.htmlを確認してください。

私のおすすめ...

pkey列を作業/一時テーブルに選択し、nullではなくデフォルト0の列(フラグ)を追加して、pkey列にインデックスを付けます。サブクエリにレコードが存在する場合は、フラグ= 1をマークします(はるかに高速です!)。メインクエリのサブ選択をexistswhereに置き換えます(temptableからpkeyを選択します。ここでflag = 0)

これがうまくいくのは、すべてを含むセットから包括的に使用できる「存在しない」値のリストを作成できることです。

これが私たちのトータルセットです。{1,2,3,4,5}

これが既存のセット{1,3,4}です

これらの2つのセット(技術的には左外部結合)から作業テーブルを作成します(record:exists)

{1:1、2:0、3:1、4:1、5:0}

「既存のレコードではない」のセット

{2,5}(* from where flag = 0を選択)

私たちの製品...そしてはるかに速い(インデックス!)

{2,5}の{1,2,3,4,5}={2,5}

{1,2,3,4,5}は{1,3,4}={2,5}にありません

これは作業テーブルなしで実行できますが、これを使用すると、何が起こっているかを簡単に視覚化できます。

クリス

于 2009-10-05T19:27:20.523 に答える