4

我一直在网上搜索书籍和谷歌咒语,试图找出叶页中的物理填充因子(SQL Server 2000 和 2005)。

我知道它是创建索引时页面上剩余的可用空间量,但我没有发现该空间实际上是如何留下的:即,它是页面末尾的一大块,还是它通过该数据有几个差距。

例如,[只是为了简单起见],假设一个页面只能容纳 100 行。如果填充因子被声明为 75%,这是否意味着页面的第一个(或最后一个)75% 是数据,其余部分是空闲的,或者每四行空闲一次(即页面看起来像:数据,数据,数据,免费,数据,数据,数据,免费,...)。

总而言之,我正在掌握在将行插入具有聚集索引的表时发生的物理操作的确切情况,并且插入没有发生在行的末尾. 如果在一个页面中留下多个间隙,则插入的影响最小(至少在页面拆分之前),因为可能需要移动以容纳插入的行数被最小化。如果间隙在表中的一大块中,那么处理行的开销(至少在理论上)会显着增加。

如果有人知道 MSDN 参考,请指点我!我现在找不到(虽然仍在寻找)。从我读过的内容来看,这暗示着它有很多差距——但这似乎并没有明确说明。

4

2 回答 2

2

来自MSDN

填充因子设置仅在创建或重建索引时应用。SQL Server Database Engine不会动态保留页面中指定百分比的空白空间。试图在数据页上保持额外空间会破坏填充因子的目的,因为在输入数据时,Database Engine必须执行页面拆分以保持每页上填充因子指定的可用空间百分比。

并进一步:

将新行添加到完整索引页面时,Database Engine会将大约一半的行移动到新页面以为新行腾出空间。这种重组称为页面拆分。页面拆分为新记录腾出空间,但可能需要时间来执行,并且是一种资源密集型操作。此外,它可能会导致碎片化,从而导致I/O操作增加。当频繁发生页面拆分时,可以通过使用新的或现有的填充因子值来重新构建索引以重新分配数据。

SQL Server的数据页由以下元素组成:

  • Page header96字节,固定。
  • Data: 多变的
  • Row offset array: 多变的。

行偏移数组始终存储在页尾并向增长。

数组的每个元素都是2保存到页面内每一行开头的偏移量的字节值。

行在数据页中没有排序:相反,它们的顺序(在集群存储的情况下)由行偏移数组确定。它是排序的行偏移量。

比如说,如果我们将100具有集群键值的 -byte 行插入10到集群表中并且它进入一个空闲页面,它会被插入如下:

[00   - 95   ]   Header
[96   - 195  ]   Row 10
[196  - 8190 ]   Free space
[8190 - 8191 ]   Row offset array: [96]

然后我们在同一页面中插入一个新行,这次集群键值为9

[00   - 95   ]   Header
[96   - 195  ]   Row 10
[196  - 295  ]   Row 9
[296  - 8188 ]   Free space
[8188 - 8191 ]   Row offset array: [196] [96]

该行在逻辑上附加,但物理上附加。

偏移数组被重新排序以反映行的逻辑顺序。

鉴于此,我们可以很容易地看到行从页面的开头开始附加到空闲空间,而指向行的指针从页面末尾开始附加到空闲空间。

于 2009-09-02T13:12:44.897 回答
0

这是我第一次想到这个,我对这个结论并不乐观,但是,

既然 SQL Server 在单个读取 IO 中可以检索的最小数据量是一完整页数据,那么为什么首先需要对单个页面中的任何行进行排序呢?我敢打赌他们不是,所以即使最后的差距都在一个很大的差距中,新记录也可以在最后添加,无论这是否是正确的排序顺序。(如果首先没有理由对页面上的记录进行排序)

其次,考虑到 thge IO 的写入端,我认为最小的写入块也是整个页面,(即使是最小的更改也需要将整个页面写回磁盘)。这意味着每次写入页面时,页面上的所有行都可以在内存中排序,因此即使您插入到单个页面上一组已排序行的开头,整个页面也会被读出,可以将新记录插入到内存集合中的适当插槽中,然后将整个新排序的页面写回磁盘...

于 2009-09-02T13:10:13.587 回答