0

ルックアップテーブル(##lookup)があります。データを複製しているのでデザインが悪いことはわかっていますが、クエリが大幅に高速化されます。このテーブルにデータを入力するクエリがあります

insert into ##lookup select distinct col1,col2,... from table1...join...etc...

この動作をシミュレートしたいと思います。

delete from ##lookup
insert into ##lookup select distinct col1,col2,... from table1...join...etc...

これにより、テーブルが明らかに正しく更新されます。しかし、これは多くの挿入と削除です。それは私のインデックスを台無しにし、選択するためにテーブルをロックします。

このテーブルは、次のような方法で更新することもできます。

delete from ##lookup where not in (select distinct col1,col2,... from table1...join...etc...)
insert into ##lookup (select distinct col1,col2,... from table1...join...etc...) except if it is already in the table

2番目の方法は時間がかかる場合がありますが、「ロックなし」と言うことができ、テーブルから選択できるようになります。

2番目の方法でクエリを作成する方法についてのアイデアはありますか?

4

2 に答える 2

2
DELETE LU
FROM ##lookup LU
LEFT OUTER JOIN Table1 T1 ON T1.my_pk = LU.my_pk
WHERE T1.my_pk IS NULL

INSERT INTO ##lookup (my_pk, col1, col2...)
SELECT T1.my_pk, T1.col1, T1.col2...
FROM Table1 T1
LEFT OUTER JOIN ##lookup LU ON LU.my_pk = T1.my_pk
WHERE LU.my_pk IS NULL

上記のLEFTJOINの代わりにWHERENOTEXISTSを使用して、存在しない行を探すこともできます。

SQL 2008を使用している場合は、MERGEステートメントを調べることもできます。そうでない場合は、テーブルの同期を維持せず、PKの同期のみを維持します。列の1つが一方のテーブルで変更され、もう一方は変更されない場合、上記には反映されません。

いずれにせよ、クエリの最適化を検討することをお勧めします。データを複製することは、パフォーマンスの問題に対する優れた修正のように思えるかもしれませんが、ご覧のとおり、データには多くの頭痛の種が伴う可能性があります(これは1つにすぎません)。この醜い盗賊を置くよりも、パフォーマンスの低下の根本的な原因を見つけて修正する方がよいでしょう。

于 2010-06-15T17:46:42.650 に答える
0

すべてのDELETEがログに記録されるため、テーブル全体を削除する予定の場合はパフォーマンスが低下します。処理している行の数によっては、ログに記録されていないTRUNCATEを使用しても問題ない場合があります。

SELECTステートメントにはどのくらい時間がかかりますか?選択に少し時間がかかり、頻繁に実行しない場合は、このようなことを試すことができます。

table1 ... join ...etc..からdistinct...INTO#tempTable1を選択します。

トランザクションドロップテーブルの開始##lookupselect * into ## lookup from#tempTable1 committransaction

トムの答えはおそらく最も堅実ですが、私はいくつかの選択肢を取り入れたいと思っていました。しかし、実際のテーブルと比較してグローバル一時テーブルが必要な理由はわかりませんか?

于 2010-06-19T23:48:14.570 に答える