2012-03-29 12 views
1

私はGUIDだけを持つテーブルTBL1を持っています。どちらが速く/より良いですか?

私は別のテーブルTBL2を持っていますが、主キーはGUIDであり、他のいくつかの列もあります。 GUIDがTBL1であるかどうかに基づいて、TBL2の列の1つを更新したいとします。

これより高速で信頼性の高いクエリはどれですか?

MERGE INTO [db].[dbo].[TBL1] AS target 
    USING [db].[dbo].[TBL2] as source 
     ON target.GUID = source.GUID 
    WHEN MATCHED THEN 
     UPDATE SET 
      StatusColumn = 0; 

または

UPDATE [db].[dbo].[TBL1] 
    SET StatusColumn=0 
    WHERE GUID IN (SELECT GUID FROM [db].[dbo].[TBL2]) 

または多分何か他のもの?

+4

あなたはそれを試して何が起こったのですか?両方のステートメントの実行計画は何を表していますか? –

+0

*一般的には、 'WHERE IN 'はお勧めしません。 「存在する場所」はより一般的に受け入れられます。しかし、神は砂漠を脇に置いています。「MERGE」は、より多くの*高速*ではありません。しかし、なぜ誰かが言葉を取る、あなた自身のすべてのオプションをテストしてみませんか? * [また、GUIDを主キーとして使用することはしばしば推奨されないことに注意してください。あなたのPKがあなたのクラスタ化されたキーである場合、テーブルはボディなしビジネスのようにフラグメント化されます - GUIDは順番に生成されないので、新しいエントリはテーブル内のランダムな位置に挿入する必要があります。* – MatBailie

+0

@Dems - いいアドバイス。私は主キーのためにGuidsを使用している場合は、クラスタ化されていないものに作成(または変更)するだけです。私たちは、その変化を生み出すことによって、私たちの環境が大幅に向上することに気付きました。 – RQDQ

答えて

3

を。あなたが掲示計画(http://i.imgur.com/6vB2t.png)から、我々は以下を参照してくださいすることができます:

  • INは左を生産している参加。これはもう少し効率的です。また、オプティマイザの弱点があり、オプティマイザが明示的な結合からセミ・ジョインを生成できない場合でも、セミ・ジョインを生成しないようにします。
  • マージで行がソートされています。これはあなたがあなたの参加から重複を得るかもしれないからです!それが不可能だったならば、マージは同じくらい速くなります。
  • 明示的な結合バージョンは、マージと同じくらい速いと思います。

計画なしでこれを診断することは、ちょうど推測です。計画を見て、そして/または測定する。測定は答えを提供しますが、この計画では答えのをと理解しています。

+1

+1は「ちょっと推測」です。 –

+0

統計情報の変更に応じて実行計画が変更されることに注意してください。断片化、並行性、および他の現実世界の要因の全ホストもそうです。静的な答えではありません。 – MatBailie

+0

計画が同じで、それらが分岐していると思われる特別な理由がない(何も考えられない)場合、それは静的な答えです。 – usr

1

私は、最速の方法は、おそらく結合を使用して第三の選択肢だと思う:この質問への答えが唯一の実行計画から来ることができる

UPDATE t1 SET StatusColumn=0 
FROM db.dbo.TBL1 t1 
INNER JOIN db.dbo.TBL2 t2 ON t1.guid = t2.guid 
+0

+1:t1のすべてのレコードがt2の0または1のレコードと一致するため、これは最速のオプションと考えています。 – MatBailie

+0

なぜそれが速くなるのでしょうか?マージは、あなたのバージョンに相当し、updateステートメントと同じです。オプティマイザが同じプランを生成できるかどうかは誰に分かりますか?私はそうではないと思う。 – usr

+0

@usr - 3つのプランすべてに対して同じ計画が生成されることがありますが、結合を使用することは、オプティマイザにあなたが何をしたいかを正確に伝える最も直接的な方法です。 –

関連する問題