0

次のステートメントを検討してください。

update TABLE1 
set FormatCode = case T.FormatCode when null then TABLE1.FormatCode else T.FormatCode end,
    CountryCode = case T.CountryCode when null then TABLE1.CountryCode else T.CountryCode end 
    <SNIP ... LOTS of similar fields being updated> 
FROM TABLE2 AS T 
WHERE TABLE1.KEYFIELD = T.KEYFIELD

TABLE1他のアプリケーションで使用されているため、ロックは最小限にする必要があり ます。他のTABLE2人は使用しないので、私は気にしません。

TABLE1TABLE2それぞれ600K行が含まれています。

上記のステートメントにより、テーブルがロックされTABLE1ますか?

最小限のロックを発生させるように変更するにはどうすればよいですか?

カーソルを使用して の行をTABLE21 つずつ読み取り、各行についてそれぞれの行を更新しTABLE1ますか?

4

2 に答える 2

1

SQL は最初に行ロックを使用します。インデックス ページに十分な数の行がロックされている場合、SQL はページ ロックを発行します。十分な数のページがロックされている場合、SQL はテーブル ロックを発行します。

したがって、発行されるロックの数に大きく依存します。update ステートメントでロック ヒント ROWLOCK を使用できます。欠点は、数百のページ ロックまたは 1 つのテーブル ロックではなく、おそらく数千の行ロックが発生することです。ロックはリソースを使用するため、ROWLOCK ヒントはおそらくテーブル ロックを発行しませんが、サーバーのリソースが枯渇し、速度が低下する可能性があるため、さらに悪いことになる可能性があります。

一度に 1000 などの更新をバッチ処理できます。Cursors は、実際にニュースをさらにアップする予定です。実験モニターは結果を分析し、収集したデータに基づいて選択を行います。

于 2012-05-10T06:19:35.543 に答える
0

提案されているようmarc_sに、より制限的な WHERE 句を導入して行数を減らすと、ここで役立つはずです。

更新は毎晩行われるため、前回の更新以降に更新されたレコード (つまり、1 日分の更新) のみを更新しようとしているようです。ただし、これは、すべてのレコードではなく、レコードのサブセットが変更された場合にのみ役立ちます。

おそらく、一時テーブルに変更された行の ID を選択してから、更新の一部として一時テーブルに参加しようとします。Id のリストを決定するには、 TABLE2 のlast changed列を使用するなど、これを行う方法についていくつかのオプションが思い浮かびます (TABLE2 に列がある場合)。または、TABLE1 と TABLE2 の間の各フィールドを比較して、それらが異なるかどうかを確認することもできます (null を監視します)。私が考えることができる3番目のオプションは、TABLE2に対してUPDATEトリガーを設定して、日中に更新される行のKEYFIELDを一時テーブルに挿入することです。夜間の更新後に一時テーブルをクリアできます。

于 2012-05-10T06:30:13.560 に答える