如果表数据具有聚簇索引,那么它是如何存储的

时间:2012-08-31 10:41:57

标签: sql indexing clustered-index

我发现了很多帖子,其开头就像很多时候我遇到过人们说“群集索引根据群集索引关键字对表格内的数据进行物理排序”。这不是真的!然后这些帖子继续描述它是如何实际存储的,通过链接列表或其他什么。例如,post表示

  

每个Index行包含一个Key值和一个指向a的指针   B树中的中级页面,或叶级别中的数据行   指数。索引每个级别的页面都链接在一个   双链表。数据链中的页面及其中的行   按聚集索引键的值排序。

这让我想到了我的问题,数据页存储表数据的地方,对吗?因此,如果对它们进行排序并且其中的数据也根据索引列值进行排序,那么为什么说聚簇索引将表数据按排序顺序保存呢?这是Kalen Delaney的书中的一张图片,其中显示CI表格中的叶子页面都根据CI值进行排序:

enter image description here

5 个答案:

答案 0 :(得分:6)

你是对的。

聚簇索引根据聚簇索引键对表内的数据进行物理排序。如果是这种情况,那么插入到没有可用空间的大表中间将需要大量的IO来为新记录腾出空间。

而是从文件中的任何位置分配新页面并链接到链接列表。

页面的物理顺序与逻辑顺序的不同程度是逻辑碎片的程度。重建或重新组织索引可以减少这种情况。

答案 1 :(得分:2)

当你创建一个索引时,还会创建一个索引表(我认为它叫做索引分配映射(IAM),不太确定名称) 对于聚簇索引,索引表包含索引列和指向实际记录的指针。

因此,当表具有聚簇索引时,数据可能无法在表上进行物理排序 .. 磁盘中的数据将作为链表维护,聚簇索引是指向该数据的指针。

现在索引表将在物理上排序...而不是实际的表...并且索引表保持为B-Tree,因此搜索速度会更快。

现在,当您创建非聚集索引时,它将指向聚簇索引表

编辑:(正如marc_s指出的那样)聚集索引的叶节点实际上包含数据,其中非聚集索引包含指针..

但我仍然不相信,它会重新排序磁盘中的数据,它只会重新排序指针

答案 2 :(得分:0)

聚簇索引按索引列对表数据进行排序。插入或更新时,每个新行都将位于表格的正确位置。

非聚集索引不会发生这种情况。

答案 3 :(得分:0)

博客文章下面清楚地解释了如何存储聚簇索引。

Does a Clustered Index really physically store the rows in key order?

答案 4 :(得分:-1)

我原来的陈述是错误的
因为任何索引 NOT 都会影响表中的数据。聚簇索引只是另一种类型的索引指向到表中的数据。它不会更改订单或对数据执行任何其他操作 在创建(聚簇或非聚簇)索引之前和之后,您始终可以使用行号直接从表中获取数据 原始声明的结尾

需要进行更正(我不经常使用MSSQL,所以以前从未有机会测试过这种情况)
似乎MSSQL实现聚簇索引根本不是一个索引,但可能更接近触发/约束对。

现在我的粗略测试:

1)

CREATE TABLE testTable ...  
INSERT ... (few rows)  
SELECT * FROM testTable  

这显示了插入顺序中的所有结果

2)

CREATE CLUSTERED INDEX ... ON testTable (...); 
INSERT ... (few rows)  
SELECT * FROM testTable  

这显示了CLUSTERED INDEX中字段排序的所有结果 3)

DROP INDEX (CLUSTERED INDEX Name) ON testTable;
INSERT ... (few rows)  
SELECT * FROM testTable  

这会再次以插入顺序显示步骤2)中的所有结果[以DROP INDEX] 之前的相同顺序以及稍后[在步骤3中插入]的行]。

对我而言,这意味着MSSQL DOES 重新排序实际数据记录(最有可能在插入/删除时花费很高)。

所以,我站起来纠正并斥责。老实说,我从未预料到这一点(CLUSTERED INDEX行为,而不是我被证明是错误的)。