我正在努力了解SQL Server 2005中的聚簇索引。我阅读了MSDN文章Clustered Index Structures(以及其他内容),但我仍然不确定我是否理解正确。
(主要)问题是:如果我将一行(带有“低”键)插入带有聚簇索引的表中会发生什么?
上述MSDN文章指出:
数据链中的页面及其中的行按聚集索引键的值排序。
例如,如果将记录添加到接近顺序排序列表开头的表中,则该记录之后的表中的任何记录都需要移动以允许插入记录。
这是否意味着如果我将一个带有非常“低”键的行插入到已经包含大量行的表格中所有行在物理上移位在磁盘上?我不能相信。这需要很长时间,不是吗?
或者更确切地说(我怀疑)有两种情况取决于第一个数据页的“完整”程度。
这将意味着数据的“物理顺序”被限制为“页面级别”(即,在数据页面内),而不是驻留在物理硬盘驱动器上的连续块上的页面。然后,数据页面以正确的顺序链接在一起。
或者以另一种方式表达:如果SQL Server需要读取具有聚簇索引的表的前N行,它可以按顺序读取数据页(在链接之后),但这些页面不是(必然)按顺序在磁盘上按顺序(因此磁头必须“随机”移动)。
我离我有多近? :)
答案 0 :(得分:3)
如果您碰巧插入一个“低”ID的行,那么是 - 它将被放置在已经存在类似ID的其他行的附近。
如果您的SQL Server页面(8K块)填充到最大值,则会发生页面拆分 - 一半行将保留在该页面上,另一半将移动到新的一页。这两个新页面现在具有一些新行的容量。
这就是为什么你不想将某些东西用作非常随机的聚类密钥的原因之一,例如:一个GUID,它将导致在整个地方插入行。
尝试避免页面拆分(这是非常昂贵的操作)是像Kimberly Tripp heavily advocate using something that is ever increasing这样的大师作为聚类键的主要原因之一 - 例如INT IDENTITY列。在这里,始终保证新值大于数据库中已有的值,因此总是在食物链的“末端”添加新行。
有关更多优秀背景信息,请参阅Kimberly Tripps的博客 - 尤其是她的Clustering Key类别!
答案 1 :(得分:2)