SQL Server 中快照隔离开启时聚集索引如何更新?

问题描述 投票:0回答:2

我有一个带有

SET ALLOW_SNAPSHOT_ISOLATION ON
的 SQL Server 2008 数据库和一个包含列 ID(主键)和 SSN(唯一非聚集索引)的 Person 表。

数据库中的其中一行 ID = 1,SSN = 776-56-4453。

一一连接,会发生这种情况:

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

正如预期的那样,即使第二个连接完成执行后,第一个连接仍将 SSN 显示为“777-77-7777”。第一个连接的执行计划在 SSN 上显示“聚集索引查找”,但是如果索引键已在另一个连接上更新,第一个连接如何继续使用索引?

SQL Server 是否做了什么特殊的事情来保留多个版本的索引来适应这种情况?

我正在尝试了解快照隔离级别的性能特征,因此想要确认 SQL Server 是否足够智能,即使在从行的先前版本中检索陈旧数据时也可以使用现有索引。

sql-server-2008 indexing snapshot-isolation
2个回答
2
投票

据我所知(使用

DBCC IND
DBCC PAGE
,如此处所述 并查看
sys.dm_tran_version_store
)在启用快照隔离的数据库中更新索引键时,会发生以下情况。

  1. 原始行被复制到版本存储中。
  2. 原始行被标记为幽灵,并更新版本指针以指向正确的位置。
  3. 为新键值插入新行。
  4. 稍后,幽灵清理进程会运行并删除该行。

您的场景中的唯一区别似乎是,幽灵清理过程不会清理该行,直到未完成的快照隔离事务不再需要该行。即 BTree 包含旧键值和新键值的行,直到不再需要它们为止,这允许对旧值的索引查找仍然像以前一样工作。


0
投票

正如 marc_s 评论

通过快照隔离,SQL Server 将放置数据的“快照” 被修改到 tempDB 中,其他连接将从那里读取。 所以你在这里的第一个连接是读取它的值和所有 tempDB 中快照副本涉及的相关索引

© www.soinside.com 2019 - 2024. All rights reserved.