2

我正在努力理解 SQL Server 2005 中的聚集索引是什么。我阅读了 MSDN 文章Clustered Index Structures(以及其他内容),但我仍然不确定我是否理解正确。

(主要)问题是:如果我将一行(带有“低”键)插入带有聚集索引的表中会发生什么?

上面提到的 MSDN 文章指出:

数据链中的页面和其中的行按聚集索引键的值排序。

以使用聚集索引为例说明:

例如,如果将一条记录添加到靠近顺序排序列表开头的表中,则表中该记录之后的任何记录都需要移动以允许插入该记录。

这是否意味着如果我将具有非常“低”键的行插入到已经包含大量行的表中,实际上所有行都在磁盘上进行了物理移动?我不能相信。这需要很长时间,不是吗?

还是(正如我怀疑的那样)有两种情况取决于第一个数据页的“完整”程度。

  • A)如果页面有足够的可用空间来容纳记录,则将其放置到现有数据页面中,并且数据可能(物理上)在该页面中重新排序。
  • B)如果页面没有足够的可用空间用于记录,将创建一个新的数据页面(磁盘上的任何位置!)并“链接”到 B 树的叶级别的前面?

这将意味着数据的“物理顺序”仅限于“页面级别”(即在数据页面内),而不是位于物理硬盘驱动器上连续块上的页面。然后数据页以正确的顺序链接在一起。

或者以另一种方式表述:如果 SQL Server 需要读取具有聚集索引的表的前 N ​​行,它可以顺序读取数据页(按照链接),但这些页在磁盘上不是(必然)按块顺序排列(所以磁盘头必须“随机”移动)。

我离我有多近?:)

4

2 回答 2

2

如果您碰巧插入了一个具有“低”ID 的行,那么是的 - 它将被放置在已经存在具有相似 ID 的其他行的附近。

如果您的 SQL Server 页面(8K 块)被填充到最大值,则会发生页面拆分- 一半的行将保留在该页面上,另一半将移动到新页面。这两个新页面现在将有一些新行的容量。

这就是为什么您不想使用非常随机的东西作为集群键的原因之一,例如 GUID,这将导致在整个地方插入行。

试图避免页面拆分(这是非常昂贵的操作)是为什么像Kimberly Tripp 这样的专家强烈主张使用不断增加的东西作为集群键的主要原因之一- 例如 INT IDENTITY 列。在这里,始终保证新值大于数据库中已有的任何值,因此始终在食物链的“末端”添加新行。

有关更多出色的背景信息,请参阅 Kimberly Tripps 的博客 - 特别是她的聚类键类别!

于 2010-04-28T12:09:25.903 回答
1

你有多近?非常!

这些文章可能有助于巩固您的理解:

http://msdn.microsoft.com/en-us/library/aa964133(SQL.90).aspx

http://www.sql-server-performance.com/articles/per/index_fragmentation_p1.aspx

于 2010-04-28T11:56:09.130 回答