0

TableToUpdateDatesという 2 つのテーブルがあります。他のテーブルDatesから見て、 TableToUpdateの EndTimeKey 列を更新する必要があります。これを行うために以下の sql を実行しますが、完了するまでに時間がかかります。

テーブルTableToUpdateには 6M のレコードがあります。Table Datesには 5000 件のレコードがあります。

どうすれば最適化できますか?

返信ありがとうございます!

update TableToUpdate set
EndTimeKey = DATE_NO
from Dates where EndTime = DATE
4

4 に答える 4

2

潜在的に 600 万件のレコードを更新していますが、これはいずれにせよ非常に高速ではありません。ただし、実行計画を見て、インデックスを使用しているかどうかを確認してください。

また、これをバッチで実行すると、多数のレコードを更新する場合に一般的に高速になります。データベースへの負荷が少ない時間外に更新を行ってください。これにより、潜在的なロックの問題が軽減されます。暗黙的な変換を行う必要がないように、2 つのテーブル間でデータ型が同じであることを確認してください。

更新しているテーブルを見てください。トリガーはありますか? トリガーの記述方法によっては、これにより多くのレコードの更新が大幅に遅くなる可能性があります (特に、あまり賢くない人がセットベースのコードを記述する代わりに、トリガーにカーソルまたはループを配置することにした場合)。

また、ここに追加するものがあります(結合を明示的に表示することも変更しました)

update t
set EndTimeKey = DATE_NO
from TableToUpdate t
Join Dates D on t.EndTime = d.DATE
where EndTimeKey <> DATE_NO

すでに一致しているレコードを更新しても意味がありません。

于 2009-02-06T16:13:51.843 に答える
0

関連するフィールドに(関連する順序で)いくつかのインデックスを設定できます。つまり、endtimekey と endtime です。これについてはあまり期待しないでください。他に確認できることは、クエリ結果を制限するための他の制約があるかどうかです。

すべての tabletoupdate.endtimekey に対して正しい date_no を返すビューを作成することもできます。

dbms がそのようなものをサポートしている場合は、ストアド プロシージャを記述できるかもしれません。これにより、更新が本当に加速されるからです。

于 2009-02-06T09:43:40.990 に答える
0

ここでいくつかのことに注意してください。EndTimeKey は本当にキーですか? その場合、インデックスがある可能性があります。その場合、データの実際の更新を行いながら速度(またはその欠如)がインデックスを更新します。ソリューションはインデックスを削除し、更新を実行してインデックスを再適用します。

別の問題は、Sql のトランザクションの性質である可能性があります。この更新を行うと、すべての変更がログに記録されるため、障害が発生した場合にロールバックできます。この更新は非常に簡単に見えるので、バッチで適用できます。

update TableToUpdate setEndTimeKey = DATE_NOfrom Dates where EndTime = DATE
where TableToUpdateId between 1 and 100000

これにより、更新が扱いやすいサイズのチャンクに分割されます。少なくとも、各チャンクにかかる時間がわかります。

もう 1 つのオプションは、EndTime 列にインデックスを配置することです。場合によっては、完全なテーブル スキャンを実行する必要があります。

ただし、実際の答えは、生成されるクエリ プランを確認することです。おわかりのように、クエリの実行が遅くなる理由は多数あります。これらは簡単に確認できる理由の一部です。

于 2009-02-06T09:43:54.187 に答える