web-dev-qa-db-ja.com

SQL-NOTEXISTSクエリのパフォーマンスを向上させる

この種のSQLクエリのパフォーマンスを向上させる方法はありますか?

INSERT
INTO ...
WHERE NOT EXISTS(Validation...)

問題は、テーブルに多くのデータ(数百万行など)がある場合、非常に遅い場合はWHERE NOT EXISTS句の実行です。重複したデータを挿入できないため、この検証を行う必要があります。

SQLServer2005を使用しています

どうも

15
Melursus

インデックス付きの列を検索していることを確認し、それらの列内のデータ(部分文字列など)を操作しないでください。

12
cjk

私の頭のてっぺんから、あなたは次のようなことを試すことができます:

 TRUNCATE temptable
 INSERT INTO temptable ...
 INSERT INTO temptable ... 
 ...
 INSERT INTO realtable
 SELECT temptable.* FROM temptable
 LEFT JOIN realtable on realtable.key = temptable.key
 WHERE realtable.key is null
11

NOTEXISTSを左外部結合に置き換えてみてください。大規模なデータセットでパフォーマンスが向上する場合があります。

6
Otávio Décio

インデックス作成に関する他の回答に注意してください。優れたインデックスがある場合、NOTEXISTSは通常非常に高速です。

しかし、私はhaveあなたが説明するようなステートメントでパフォーマンスの問題がありました。私が回避するために使用した1つの方法は、候補値に一時テーブルを使用し、DELETE FROM ... WHERE EXISTS(...)を実行してから、残りを盲目的にINSERTすることです。もちろん、トランザクション内では、競合状態を回避します。クエリを分割すると、オプティマイザが混乱することなくジョブを実行できる場合があります。

1
dwc

問題のスペースを減らすことができれば、パフォーマンスが大幅に向上します。そのテーブルのこれらの行をすべてチェックする必要があることを絶対に確信していますか?

あなたが試してみたいかもしれない他のことはDELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria>挿入前。ただし、マイレージは異なる場合があります

0
hova
insert into customers 
select * 
from newcustomers 
where customerid not in (select customerid 
                         from customers)

..より効率的かもしれません。他の人が言っているように、ルックアップフィールドにインデックスがあることを確認してください。

0
SqlACID

アウターアプライは私のために働く傾向があります...

の代わりに:

from t1
where not exists (select 1 from t2 where t1.something=t2.something)

私が使用します:

from t1
outer apply (
    select top 1 1 as found from t2 where t1.something=t2.something
) t2f
where t2f.found is null
0
b_levitt