寻找可视化来了解分配顺序扫描如何导致丢失/重复的行?

var*_*ble -2 sql-server

在读未提交隔离模式下,SQL Server引擎可能决定使用索引顺序扫描或分配顺序扫描。

由于此答案的答案中提到的原因,索引顺序扫描可能会导致丢失/重复行:丢失的行和重复的行是否是由于分配顺序扫描或由于无锁和页拆分而导致的症状?。链接的答案包含一个显示可视化效果的图表。

分配顺序扫描也可能导致丢失/重复的行,正如上面的答案中提到的,这是因为页面拆分。我正在寻找这个的可视化。

Pau*_*ite 6

在读未提交隔离模式下,SQL Server引擎可能决定使用索引顺序扫描或索引顺序分配扫描。

不存在“索引顺序分配扫描”这样的东西。有索引顺序扫描和分配顺序扫描。

我正在寻找这一点的可视化。

我不打算画图,但想象一个包含如下页面的索引:

下一页
500 000-099 300
300 100-199 700
700 200-299

页码是它们在文件中的物理位置。所以第 500 页是物理文件中的第 500 个 8KB 页。

请注意,物理页 ID 与索引键顺序不匹配

例如,物理页500包含键(000-099),其低于页300上的键(100-199)。这是完全正常且允许的。

在这个(非常)简化的示例中,单个 IAM 页涵盖了该分配范围。IAM 页面告诉我们第 300、500 和 700 页属于该索引(这就是它告诉我们的全部内容)。

现在,索引的分配顺序扫描从第 300 页(根据 IAM 属于该索引的最低物理页号)开始。

与此同时,另一个进程导致第 500 页分裂:

下一页
500 000-049 100
300 100-199 700
700 200-299
100 050-099 300

一半的行已从第 500 页移动到(新的)第 100 页。由于我们使用分配顺序扫描,因此我们不遵循下一页指针。相反,我们继续查看 300 页之后的下一个编号较高的页面,即 500,然后是 700。

我们从未遇到过第 100 页上的行。由于页拆分和分配顺序扫描,这些行“丢失”。


如果第 500 页的拆分导致编号高于 300 的新页,我们会在分配顺序扫描期间遇到它。没有缺失行,也没有重复。


作为最后一个例子,假设我们已经读取了第 300 页,现在正在处理第 500 页。此时,另一个进程导致第 300 页拆分,创建新的第 600 页。我们将遇到第 600 页上的行两次:一次是当我们读取时拆分前的第 300 页,以及拆分后遇到的第 600 页。