2016-03-24 10 views
0

WHERE NOT EXISTSを使用している以下のクエリを改善することができますか?INSERTステートメントから存在しないWHERE NOT EXISTS

キーがテンポラリテーブルにある場合、バッチ数500の別のテーブルのレコードを別のテーブルに追加したいのですが、それは機能しますが、可能であればパフォーマンスを向上させたいと考えています。

WHILE 1 = 1 

BEGIN 

INSERT INTO newTable WITH (TABLOCK) 
     SELECT TOP(500) * 
     FROM srcTable src 
     WHERE NOT EXISTS (SELECT 1 FROM newTable WHERE pKey = src.pKey 
          AND src.pKey IN (SELECT pKey FROM #TempTable)) 

IF @@ROWCOUNT < 500 BREAK 
END 

ありがとうございます!

+2

というバッチサイズを増やすことから始めます。 500行は非常に小さいです。私は10kが速すぎる反復ではなく、余りにも多くの反復を終わらせるという転倒点の周りにあると思うだろう。 –

+0

#TempTableにいくつの行がありますか? – FLICKER

+0

#TempTableに7072レコードがあります – Billy

答えて

0

not existsに両方の条件を入れるのは奇妙です。だから私は思っている:

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      NOT EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 

はその後、このクエリのために、私はnewTable(pkey)#TempTable(pkey)のインデックスをしたいと思います。

注:私はその論理が正しいと思います。関連するNOT EXISTSの関係のないテーブルにINを入れるのはちょっと混乱します。

編集:

Hmmm。 。 。そのロジックが間違っている場合は、

INSERT INTO newTable WITH (TABLOCK) 
    SELECT TOP(500) * 
    FROM srcTable src 
    WHERE NOT EXISTS (SELECT 1 FROM newTable nt WHERE nt.pKey = src.pKey) AND 
      EXISTS (SELECT 1 FROM #TempTable tt WHERE src.pKey = t.pkey); 
+0

'存在しない 'フォームではなく、srcTableと#TempTableの間で'内部結合'を行う方が効率的な条件はありますか? –

+0

@PhilipKelley。 。 。 '存在しない'を '内部結合 'に置き換える方法は考えられません。あなたは '左外部結合 'で置き換えることができます、そして、私は性能が匹敵すると思います。少なくとも、どちらのバージョン( 'left join'と' not exist'/'not in')は、現在のクエリよりも優れています。 –

+0

私がそれを読んでいるところでは、OPは#tempテーブルにIDが存在する場合のみnewTableからデータをコピーしたいのですが、まだコピーされていない場合に限ります。したがって、#tempにnewTableを追加し(正当なターゲットを取得するだけです)、まだコピーされていなければコピーします( 'not exists'でチェックされています)。 –

関連する問題