1

SQL Server を使用してデータベース内でデータを処理するための最良の方法について、ガイダンスを探しています。

基本的に、データがロードされた一連の一時テーブルがあり、それらに対して一連の更新ステートメントが実行されます。これらの一連の更新ステートメントの複数のインスタンスが同じテーブルに対して実行されますが、各インスタンスは特定の識別子 (系列) を持つ行のみを更新します。インスタンスが同時に実行されているときのロックの問題/デッドロックを自信を持って回避できるようにしたいと考えています。

これについて私が考えたのは次の2つです。

  1. すべての update ステートメントにはヒント行ロックが含まれているため、異なる系列をカバーするページ ロックは発生しません。
  2. 分離レベルを変更します。ダーティ リードが実際に発生することはありません。この状況への最良のアプローチである可能性があることに誰かが光を当てることができますか?
4

1 に答える 1

1

テーブルが次のようになっていると仮定します。

CREATE TABLE MyTable
( 
   ID INT IDENTITY(1,1),
   LineageId INT NOT NULL, -- FK to Lineage
   Col1 ...
   Col2 ...

   PRIMARY KEY CLUSTERED(ID),
   FOREIGN KEY LineageId REFERENCES Lineage(LineageId)
) 
  1. テーブルのクラスター化インデックスを LineageId に変更することをお勧めします (ただし、後述します)。これにより、SQL が行ロックをページ ロックにエスカレートした場合に、更新されるページが最も少なくなることが保証されます。これの欠点は、LineageId が一意ではないため、SQL が一意識別子を追加することです。したがって、クラスタリングを変更する前に、PK が増加していて、テーブル内のほとんどすべての行が LineageId によってすでに連続して配置されていることがわかった場合 (たとえば、データが単一のスレッド化されたバッチ ジョブによってこのテーブルに挿入された場合)、サロゲート pkey をインクリメントすることは、uniquifier を回避するため (狭さの改善) 好ましいでしょう。

  2. これは保証ではありませんが、ROWLOCK ヒントが役立つ場合があります。 http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/60238304-04e8-4f98-84d1-3ddf1ed786a9

  3. 分離レベルを (NOLOCK) ヒントに設定するREAD UNCOMMITTEDか、SNAPSHOTまたは (NOLOCK) ヒントを使用して、テーブルへの LineageId の更新中にブロックされないようにするために、他の同時クエリに対して実行する必要があります。これは抜本的な対策であり、コミットされていない読み取りは整合性の問題につながる可能性があります。

于 2012-05-21T04:37:01.963 に答える