1

SQL Server 2008 データベースとSET ALLOW_SNAPSHOT_ISOLATION ON、列 ID (主キー) と SSN (一意の非クラスター化インデックス) を持つ Person テーブルがあります。

データベース内の行の 1 つは、ID = 1、SSN = 776-56-4453 です。

1 つ 1 つの接続で、次のことが起こります。

set transaction isolation level snapshot
begin transaction snapshot
while (1 = 1) select * from person where SSN = '777-77-7777'

次に、別の接続で:

update person set SSN = '555-55-5555' where ID = 1

予想どおり、最初の接続では、2 番目の接続の実行が終了した後も SSN が '777-77-7777' として表示され続けます。最初の接続の実行計画は、SSN で「クラスター化されたインデックス シーク」を示していますが、他の接続でインデックス キーが更新されている場合、最初の接続はどのようにインデックスを使用し続けることができますか?

これに対応するために、SQL サーバーは複数のバージョンのインデックスを保持するために何か特別なことをしますか?

スナップショット分離レベルのパフォーマンス特性を理解しようとしているので、行の以前のバージョンから古いデータを取得する場合でも、SQL Server が既存のインデックスを使用できるほどスマートであることを確認したいと考えています。

4

2 に答える 2

1

スナップショット分離が有効になっているデータベースでインデックス キーを更新すると、私が知る限り (ここで説明されているようにDBCC INDとを使用して を参照)、次のことが起こります。DBCC PAGE sys.dm_tran_version_store

  1. 元の行がバージョン ストアにコピーされます。
  2. 元の行はゴーストとしてマークされ、正しい場所を指すようにバージョン ポインターが更新されます。
  3. 新しいキー値用に新しい行が挿入されます。
  4. その後、ゴースト クリーンアップ プロセスが実行され、行が削除されます。

シナリオの唯一の違いは、未処理のスナップショット分離トランザクションで不要になるまで、ゴースト クリーンアップ プロセスが行をクリーンアップしないことです。つまり、BTree には、必要がなくなるまで古いキー値と新しいキー値の両方の行が含まれます。これにより、古い値に対するインデックス シークが以前と同様に引き続き機能します。

于 2012-05-20T11:28:08.447 に答える
0

スナップショット分離を使用すると、SQL Server は変更中のデータの "スナップショット" を tempDB に配置し、他の接続はそこから読み取ります。したがって、ここでの最初の接続は、その値と、tempDB のスナップショット コピーから関連するすべてのインデックスを読み取ることです。

于 2012-05-20T09:21:13.417 に答える