知识卡片
前缀压缩索引:用"二分查找"换磁盘空间
内容
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
内存资源与磁盘之间做权衡。