知识卡片

堆文件聚簇索引与覆盖索引在读取速度和写入开销间的三级权衡

普通读书笔记卡

内容

索引里的值可以是实际数据本身,也可以只是指向数据真正存放位置的引用,这个选择有 三个层级。最基础的是堆文件方式:索引只存一个指针,实际的行/文档存在别处一个称为 堆文件的地方,数据没有特定顺序;这种方式的好处是当存在多个二级索引时避免了数据 重复——每个索引只引用堆文件中的一个位置,实际数据只保存一份,更新时只要新值不比 旧值大,甚至可以原地覆盖,很高效;缺点是每次查询都要多一次”从索引跳到堆文件”的 额外开销。第二级是聚簇索引:直接把行数据存进索引本身,不再需要额外的堆文件跳转, 省掉了这次跳跃开销(比如MySQL InnoDB里表的主键就是聚簇索引,二级索引则引用主键 而非堆位置)。第三级是介于两者之间的折衷——覆盖索引(或称包含列的索引):只把表的 一部分列存进索引内,让某些查询只靠索引本身就能返回结果、完全不用去访问主表数据。 这三级选择的本质是同一种权衡的不同程度:把数据放得离索引越近,读取跳转越少、速度 越快,但代价是索引需要占用更多存储空间,写入时需要维护更多份重复数据,数据库还要 额外确保这些重复副本之间的事务一致性,避免应用看到不一致的结果。

参考来源

- 位置:《数据密集型应用系统设计》第三章《存储与检索》"将值存储在索引中"(源文件: _epub-src/ch3_split_002.html) - 结论依据:原文说明堆文件方式索引只存引用避免数据重复但需额外跳转、聚簇索引直接 在索引中存储行数据省去跳转、覆盖索引存储部分列作为折衷,并指出这类重复数据能 加快读取但需要额外存储空间和写入开销及事务一致性保证,直接支撑本卡片的三级 权衡梳理。 - 原始内容:堆文件方法很常见,因为它避免了在存在多个二级索引时复制数据……在某些 情况下,从索引到堆文件的额外跳跃对读取来说性能损失太大,因此可能希望将索引行 直接存储在索引中。这被称为聚簇索引……被称为包含列的索引或覆盖索引……聚集和 覆盖索引可以加快读取速度,但是它们需要额外的存储空间,并且会增加写入开销。