0

そのため、次のようにバッチで実行することにより、大規模なテーブル (100m 以上のレコード) を更新するのに役立つはずのコードに出くわしました。

--Declare variable for row count
set rowcount 50000
go

Declare @rc int
Set @rc=50000

While @rc=50000
 Begin

  Begin Transaction

  --Use tablockx and holdlock to obtain and hold 
  --an immediate exclusive table lock. This unusually
  --speeds the update because only one lock is needed.

    update  MyTable With (tablockx, holdlock)
    set TestField='ABC'

    ----Get number of rows updated
    ----Process will continue until less than 50000
    select @rc=@@rowcount


  Commit
 End

問題は、これが無限ループに入り、日の終わりまで priting (影響を受ける 50000 行) になることです。ちなみに、テーブルのレコード数が 50000 未満の場合、上記のコードは正しく終了します。誰でもこれを修正する方法を知っていますか?

ありがとう

4

1 に答える 1

3

MyTable に 50000 以上のレコードがある場合、常に更新されます。最終的に 50000 件未満のレコードが更新されるようにフィールドを絞り込む更新には where 句がありません。

おそらく、TestField <> 'ABC' のレコードのみを更新するつもりだったので、同じ更新を再度実行しませんでした。

どの where 句を使用するかを検討している場合は、クラスター化インデックスを使用することを検討してください。これにより、完全なテーブル スキャンではなく、更新時にインデックス シーク/部分スキャンを実行できるようになります。

なお、HOLDLOCKヒントはトランザクションがコミットするとすぐに解放されるので必要ありませんし、更新自体がトランザクションなので明示的なトランザクションも必要ありません。タブロックはロックのエスカレーションを回避するため、わずかに改善される可能性があります。

于 2012-05-10T15:21:15.983 に答える