我发现了很多帖子,其开头就像很多时候我遇到过人们说“群集索引根据群集索引关键字对表格内的数据进行物理排序”。这不是真的!然后这些帖子继续描述它是如何实际存储的,通过链接列表或其他什么。例如,post表示
每个Index行包含一个Key值和一个指向a的指针 B树中的中级页面,或叶级别中的数据行 指数。索引每个级别的页面都链接在一个 双链表。数据链中的页面及其中的行 按聚集索引键的值排序。
这让我想到了我的问题,数据页是存储表数据的地方,对吗?因此,如果对它们进行排序并且其中的数据也根据索引列值进行排序,那么为什么说聚簇索引将表数据按排序顺序保存呢?这是Kalen Delaney的书中的一张图片,其中显示CI表格中的叶子页面都根据CI值进行排序:
答案 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行为,而不是我被证明是错误的)。