数据库页压缩省下的是磁盘空间和磁盘 I/O,它的代价主要体现在两个容易被忽略的地方:一是读取压缩页时必须由 CPU 完成解压,高并发下解压时间会累积成实打实的 CPU 占用;二是 Buffer Pool 里压缩页和解压页是双层结构,缓存能装下多少 "可直接服务请求" 的逻辑页,不能只看物理内存大小和压缩比。压缩比越高,同样内存能缓存的逻辑页越多,但只要访问到的压缩页没有配套的解压页,就要现场解压一次;访问模式分散、解压页留不住时,同样的逻辑页可能被反复解压,缓存收益被解压成本稀释。写密集场景下还要再叠加一次压缩往返和页重组带来的写入放大。判断一张表该不该开页压缩,先看 CPU 余量够不够、读写比是多少、数据本身压缩率高不高,而不是看到磁盘告警就直接加压缩。
一、页压缩在 Buffer Pool 里的存储机制
InnoDB 页压缩的作用对象是默认 16KB 的数据页。开启后,页在落盘前被压缩,读取时再解压。Buffer Pool 中的关键设计是 "压缩页 + 解压页" 双层结构:
- 磁盘上只保存压缩后的页;
- 内存空间充足时,Buffer Pool 可能同时保留压缩页和对应的未压缩页;
- 查询访问某页时,如果 Buffer Pool 里已有解压页,直接读取;如果只有压缩页,需要先解压才能返回数据;
- 内存紧张时,系统按 I/O 瓶颈或 CPU 瓶颈选择驱逐策略,决定先丢掉哪一份副本。
| 系统状态 | 驱逐策略倾向 | 直接影响 |
|---|---|---|
| I/O 瓶颈明显 | 优先驱逐解压页,保留压缩页 | 让更多磁盘页驻留内存,减少读盘次数 |
| CPU 瓶颈明显 | 压缩页和解压页一起驱逐 | 把内存留给热点页,避免在内存中反复解压 |
二、代价一:解压消耗 CPU,高并发读可能成为新瓶颈
压缩算法的解压属于 CPU 密集型操作。单次解压一个 16KB 页面通常是微秒级,单看很小;但高并发读场景下每秒可能有数万次页访问,解压操作累积起来会直接体现在系统 sys 时间和 CPU 利用率上。
可参考的量化表现:
- 读密集型表开启 zlib 压缩后,QPS 可能出现约 10% 量级的下降,CPU 利用率上升约 12 个百分点;
- 这时 QPS 下降往往不是磁盘 I/O 卡住,而是 CPU 把时间花在解压上,挤占了查询执行本身;
- 判断逻辑:如果当前 CPU 利用率已经在 60% 以上,且读请求密集,开启页压缩后 CPU 可能先于磁盘成为新瓶颈。
算法选择会直接影响这部分 CPU 成本:
| 算法特点 | 压缩比 | 压缩 / 解压速度倾向 | 适用取向 |
|---|---|---|---|
| zlib | 压缩比好 | 压缩、解压相对慢 | 磁盘空间优先、CPU 有余量的场景 |
| lz4 / lz4hc | 与 zlib 接近 | 解压速度快很多 | 读频繁、希望降低解压 CPU 开销的场景 |
百度在 MySQL 页压缩实践中的测试显示,lz4hc 解压速度可达 586.45 MB/s,约为 zlib 的 8.75 倍;在 SSD 场景下配合后台异步压缩,读性能相比未压缩方案有改善空间。
三、代价二:Buffer Pool 有效容量不等于逻辑容量
压缩页在内存里占的物理空间更小,直觉上同样大小的 Buffer Pool 能缓存更多逻辑页,命中率应该上升。实际情况要复杂一层:
- 解压是按需发生的:命中压缩页后,仍需解压才能返回数据;
- 解压次数不等于页访问次数:真正决定解压开销的是 "压缩页命中、但解压页未命中" 的频率;
- 解压页不一定留得住:如果 Buffer Pool 不足、页面访问频率低,解压后的页可能很快被驱逐,下一次访问同一逻辑页时要再解压一次;
- 访问模式分散会放大问题:页复用率低时,缓存带来的收益被反复支付的解压成本抵消,Buffer Pool 的 "有效可服务容量" 被打折。
也就是说,Buffer Pool 有效容量要同时看三件事:压缩页能装多少、解压页能留住多少、同一页面被重复访问的频率有多高。只按压缩比估算内存收益,容易高估缓存效果。
四、代价三:写入放大与压缩往返开销
写密集场景下,页压缩的代价更直接:
- 每次写入或更新页面,需要先压缩再落盘,压缩本身消耗 CPU;
- 页面被频繁修改时,压缩 / 解压往返次数随写入频率增长;
- 压缩页在内存中被修改后,需要重新压缩才能写回磁盘;
- 压缩页修改可能触发页重组,伴随额外碎片和 I/O。
可参考的量化表现:写密集日志表开启 zlib 压缩后,写入 TPS 可能下降约 25%,磁盘写入量在重组和碎片影响下甚至略有上升,磁盘节省被写入路径的 CPU 开销和 I/O 放大抵消一部分。
五、适合开启与建议绕开的场景对照
| 维度 | 适合开启页压缩 | 建议绕开或暂缓 |
|---|---|---|
| 读写比例 | 读多写少,写入压力轻 | 写密集的交易表,压缩往返频繁 |
| 资源瓶颈 | 磁盘 I/O 是明确瓶颈,利用率长期偏高 | CPU 已接近瓶颈,解压会加剧争用 |
| CPU 余量 | CPU 利用率有充足余量 | CPU 长期高负载,无解压预算 |
| 数据特征 | 文本、日志、JSON 等冗余度高、压缩率好 | 数据本身压缩率低,省下的空间有限 |
| 访问模式 | 热点页集中、页复用率高,解压页留得住 | 访问模式分散、页复用率低,解压反复发生 |
如果问题只是磁盘告警,更精细的做法是先做表分区和冷数据归档,把不常访问的历史数据迁到独立表空间或对象存储,而不是对整张热表开启压缩。压缩是表级全局生效,分区归档是更细粒度的空间控制。
六、优化方向与上线前检查清单
算法与机制层面
- 优先评估解压更快的算法(如 lz4 系列),在压缩比可接受的前提下降低单次解压 CPU;
- 写入路径考虑后台异步压缩,把压缩耗时从写入关键路径上移开;
- 监控压缩页、解压页在 Buffer Pool 中的占比和驱逐情况。
上线前检查清单
- 当前 CPU 利用率是否有余量承载解压开销;
- 表是读多写少还是写多读少;
- 样本数据的实际压缩率是多少;
- 热点页是否集中,解压后能否被复用;
- 压测对比开启前后的 QPS、TPS、CPU sys 时间、Buffer Pool 命中率;
- 确认文件系统是否支持稀疏文件、洞裁剪(hole punching)等配套能力。
七、小结
页压缩本质上是用 CPU 时间换磁盘空间和 I/O,代价不在压缩算法本身,而在解压发生的频率和位置:高并发读时解压挤占 CPU,写密集时压缩往返放大写入开销,访问模式分散时缓存收益被解压成本稀释。评估时把解压 CPU 开销和 Buffer Pool 有效容量放在一起看,结合读写比、CPU 余量和数据压缩率做判断,才能避免省了磁盘、拖慢了业务。
【常见问题】
问题 1:为什么开了页压缩之后 CPU 反而升高,这部分解压 CPU 开销花在哪?
回答 1:页压缩读取压缩页时需要由 CPU 现场解压,高并发下每秒大量页面访问会把解压时间累积到系统 sys 时间上;解压 CPU 开销主要花在 "压缩页命中、解压页未命中" 的访问路径上,访问越分散、解压页越留不住,重复解压越多,CPU 占用越明显。
问题 2:Buffer Pool 有效容量为什么不能按压缩比直接算?
回答 2:页压缩在 Buffer Pool 里是压缩页加解压页的双层结构,压缩页占内存少,但要能直接服务请求还得有解压页;Buffer Pool 有效容量取决于压缩页装载量、解压页留存率和热点页复用频率,只按压缩比估算会高估缓存收益。
问题 3:读多写少、磁盘吃紧的表,适合直接开页压缩吗?
回答 3:这类表是页压缩的主要适用方向,但前提是 CPU 有余量、数据压缩率好、热点页集中;建议先压测对比 QPS、TPS、CPU sys 时间和 Buffer Pool 命中率,确认解压 CPU 开销可接受后再全量开启。
问题 4:写密集的表开启页压缩,除了解压 CPU 开销还会有什么影响?
回答 4:写密集表每次修改页面都要重新压缩落盘,压缩 / 解压往返随写入频率增长,压缩页重组还可能带来碎片和额外 I/O,形成写入放大;这类表更建议先做冷数据归档和分区,而不是直接对热表开启页压缩。
【参考资料】
- [2026-11-13](页压缩的代价到底在哪 —— 解压的 CPU 开销和 Buffer Pool 的有效容量)腾讯云开发者社区
- [2026-11-13](MySQL 标签开发者社区文章汇总)华为云开发者
- [2026-11-06](云数据库 MySQL 列压缩算法与压缩级别说明)腾讯云
- [2026-09-02](MariaDB Page Compression: Speicherplatz sparen mit minimalen Performanceeinbußen)webhosting.de
- [官方手册](How Compression Works for InnoDB Tables)MySQL Reference Manual
- [官方手册](Tuning Compression for InnoDB Tables)MySQL Reference Manual
- [学术论文](Leveraging Page-Level Compression in MySQL — a Practice at Baidu)南开 - 百度联合实验室
- [2024-09-24](LZ4 压缩数据结构与速度指标解析)墨天轮数据库社区
【免责声明】
本文内容基于公开技术资料、官方手册与实践论文整理,仅用于数据库原理交流与性能评估参考,不构成生产环境架构变更、参数配置或压缩方案选型的直接建议。文中涉及的性能数据、CPU 占比、TPS/QPS 变化和算法速度对比,均来自特定测试环境与数据集,实际表现受硬件配置、MySQL/MariaDB 版本、页大小、数据特征、并发模型和磁盘类型影响,需结合自身压测结果判断。引用的外部资料版权归原出处所有,如表述存在偏差,以官方文档及原始文献为准。
