2012-03-26 10 views
4

多くの開発者と同様に、私はデータ、特にSQL Serverで多くのマージ操作を実行します。マージ操作中にテーブルを更新する最も効率的な方法は何ですか?

歴史的に、私は古いトリックを使用している: - 左をやって)

1は、既存のデータに参加する、と私はのために対応するレコードを持っていない何かを挿入します。

2)1)の後、ターゲットテーブルの行を更新します。

私は1)でパフォーマンスヒットする必要があります。やむを得ないことだ。しかし、2)では、私はむしろ恥ずかしそうでした。更新が必要なものを更新するだけでなく、私がマッチしたもの(基礎となるデータが変更されたかどうか)をすべて更新しました。

SQL Serverは、この種の更新についてスマートではないことがわかりました。それはあなたが更新しようとしているものがあなたがそれを更新するために使用しているものと同じではないことを決定するために事前チェックを実行しません。したがって、これらの行に沿って行われる更新は、物理的な書き込みをもたらし、フィールドを参照するインデックスに影響を与えます。次のように私のPOVから、私の選択肢があるので

、: -

1)私のルーチンの現在の浪費を浴び、通常のようにキャリー(と大型のDBで毎日のインデックスを更新)

  • 長所:それは簡単です。
  • 短所:それは駄目です。

2)フィールドが変更されている場合は、特定のフィールドを更新するUPDATEステートメントをさらに記述します。

UPDATE 
    p2 
SET 
    [SpecificField] = p1.[SpecificField] 
FROM 
    @source p1, 
    Dest p2 
WHERE 
    p2.ExternalKey = p1.ExternalKey 
AND COALESCE(p1.[SpecificField],'') <> COALESCE(p2.[SpecificField],'') 
  • 長所:それは、高度に特異的だアップデートが必要な場合にのみ更新します。
  • 短所:多数の列を持つテーブルの異なる更新ステートメントのロット。

3)スタックオーバーフローコミュニティが示唆しているように無限に優れたものがあります。

3)と一緒に行きたいです。私のオプションは本当に1か2に制限されていますか?注意。私はMERGE INTOを調べました。同じ問題、本当に。

+0

SQL Server?バージョン?あなたは 'MERGE'ステートメントを使用することができるかもしれません... – JNK

+0

私は2008年がMERGE INTOに付属していることを知っていますが、それはインデックスに影響すると同じ問題を抱えていませんか? –

+0

値が変更されていないフィールドを更新する場合は、はいとします。それぞれのフィールドに 'CASE'チェックをつけることができます。 – JNK

答えて

1

MERGE INTOには、WHEN (NOT) MATCHED句に追加の検索句を追加するオプションがあります。例えば、

MERGE INTO table_to_upsert AS target 
USING source_table AS source 
    ON target.key1 = source.key1 
    AND target.key2 = source.key2 
    AND target.key3 = source.key3 
WHEN MATCHED AND (target.value <> source.value) THEN 
      UPDATE SET target.value  = source.value, 
         target.timestamp = source.timestamp 
WHEN MATCHED AND (target.userid <> source.userid) THEN 
      UPDATE SET target.userid = source.userid, 
         target.timestamp = source.timestamp 
WHEN NOT MATCHED THEN 
      INSERT (key1, key2, key3, 
        value, userid, timestamp) 
      VALUES (source.key1, source.key2, source.key3, 
        source.value, source.userid, source.timestamp) 

しかし、これは実際に複数の列を一度に更新される場合、MERGEは(CASEの文に類似)真評価された最初のWHEN (NOT) MATCHEDを取ると、あなたの問題を解決していません。

+0

最後の文まではすごくうまくいっていた! (これは残念ながら答えになる可能性があります)。入力を感謝します、サー! –

+0

これは試しましたか? SQL Server 2012では、 'WHEN MATCHED'タイプのアクションがMERGEステートメントの 'UPDATE'句に複数回出現することはできません.SQL Server 2008ではこれと異なるのですか? –

+2

[マージドキュメント](http://technet.microsoft.com/en-us/library/bb510625.aspx)。 msgstr "" "WHERE MATCHED節が2つある場合、UPDATEアクションを指定し、DELETEアクションを指定する必要があります" –

関連する問題