この種のSQLクエリのパフォーマンスを向上させる方法はありますか?
INSERT
INTO ...
WHERE NOT EXISTS(Validation...)
問題は、テーブルに多くのデータ(数百万行など)がある場合、非常に遅い場合はWHERE NOT EXISTS
句の実行です。重複したデータを挿入できないため、この検証を行う必要があります。
SQLServer2005を使用しています
どうも
インデックス付きの列を検索していることを確認し、それらの列内のデータ(部分文字列など)を操作しないでください。
私の頭のてっぺんから、あなたは次のようなことを試すことができます:
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
NOTEXISTSを左外部結合に置き換えてみてください。大規模なデータセットでパフォーマンスが向上する場合があります。
インデックス作成に関する他の回答に注意してください。優れたインデックスがある場合、NOTEXISTSは通常非常に高速です。
しかし、私はhaveあなたが説明するようなステートメントでパフォーマンスの問題がありました。私が回避するために使用した1つの方法は、候補値に一時テーブルを使用し、DELETE FROM ... WHERE EXISTS(...)を実行してから、残りを盲目的にINSERTすることです。もちろん、トランザクション内では、競合状態を回避します。クエリを分割すると、オプティマイザが混乱することなくジョブを実行できる場合があります。
問題のスペースを減らすことができれば、パフォーマンスが大幅に向上します。そのテーブルのこれらの行をすべてチェックする必要があることを絶対に確信していますか?
あなたが試してみたいかもしれない他のことはDELETE InsertTable FROM InsertTable INNER JOIN ExistingTable ON <Validation criteria>
挿入前。ただし、マイレージは異なる場合があります
insert into customers
select *
from newcustomers
where customerid not in (select customerid
from customers)
..より効率的かもしれません。他の人が言っているように、ルックアップフィールドにインデックスがあることを確認してください。
アウターアプライは私のために働く傾向があります...
の代わりに:
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