知识卡片

前缀压缩索引:用"二分查找"换磁盘空间

普通读书笔记卡

内容

MyISAM的前缀压缩索引是一种典型的”用CPU/查找效率换存储空间”的具体 机制:同一个索引块内,只完整保存第一个值,后面每个值只存”和前一个值 共享的前缀长度+剩余不同的后缀”,比如索引块第一个值是”perform”、下一个 是”performance”,第二个值实际存储的是”7,ance”这种紧凑形式。这样确实 能大幅压缩索引体积(可能只需要原来十分之一的磁盘空间),对I/O密集型 场景很有价值,因为更小的索引能更完整地放进内存,减少磁盘访问。但这个 空间收益背后有一个容易被忽视的结构性代价:因为每个值的压缩表示都 依赖前一个值才能还原出完整内容,索引块内部就不再具备”任意跳转比较” 的能力,无法再用二分查找定位,只能从头开始线性扫描——原本二分查找 是B-Tree索引查找效率的核心保证,前缀压缩为了省空间,实质上放弃了这 一层结构性优势,把索引块内的查找复杂度从对数级退化成了线性级。这个 代价在正序扫描时还不算严重,但在倒序扫描(比如ORDER BY DESC)时 会更差;对CPU密集型应用来说,压缩索引反而会让查找变慢好几倍。这个 案例是”存储与计算的工程权衡”最直接的例子之一:磁盘空间和内存命中率 是一类资源,CPU计算和查找效率是另一类资源,前缀压缩索引把资源占用 从前者转移到了后者,选不选用它取决于具体系统究竟是I/O密集型(省 空间收益大于查找变慢的代价)还是CPU密集型(查找变慢的代价盖过省 空间的收益),不存在无条件正确的默认选择。

参考来源

- 位置:《高性能MySQL:第3版》第5章"创建高性能的索引"5.3.8节"压缩 (前缀压缩)索引"(源文件:_epub-src/OEBPS/Text/part0012.xhtml) - 结论依据:原文明确"因为每个值的压缩前缀都依赖前面的值,所以MyISAM 查找时无法在索引块使用二分查找而只能从头开始扫描……测试表明,对于 CPU密集型应用,因为扫描需要随机查找,压缩索引使得MyISAM在索引 查找上要慢好几倍……压缩索引需要在CPU内存资源与磁盘之间做权衡", 直接说明前缀压缩索引放弃二分查找能力的机制及其CPU与磁盘资源之间 的权衡本质。 - 原始内容:因为每个值的压缩前缀都依赖前面的值,所以MyISAM查找时 无法在索引块使用二分查找而只能从头开始扫描……压缩索引需要在CPU 内存资源与磁盘之间做权衡。