当前位置: 首页 > news >正文

MySQL表压缩:用CPU换I/O的秘密武器

这段内容是 MySQL 官方文档 17.9.1.1 节:InnoDB 表压缩概述(Overview of Table Compression),它深入解释了 InnoDB 表压缩的工作原理、优势、限制和内存使用机制

我们来逐段拆解、翻译并通俗化讲解,让你彻底理解这个技术的核心思想。


🎯 一句话总结

InnoDB 表压缩 通过牺牲少量 CPU 资源,换来 更小的数据存储、更少的磁盘 I/O 和更高的性能,特别适合 读多写少的场景和 SSD 存储。但它要求使用独立表空间(.ibd 文件),并且在内存中会同时缓存压缩页和解压页,需合理规划 Buffer Pool 大小。


🔍 一、为什么需要压缩?—— 现代数据库的瓶颈转移

文档第一段说:

“Because processors and cache memories have increased in speed more than disk storage devices, many workloads are disk-bound.”

✅ 通俗解释:

  • CPU 和内存(RAM)的速度提升远快于磁盘
  • 所以现在大多数数据库性能瓶颈不在 CPU,而在 磁盘 I/O(读写速度慢)

📌 比如:

  • 从内存读数据:纳秒级(ns)
  • 从 SSD 读数据:微秒级(μs)→ 慢 100~1000 倍
  • 从 HDD 读数据:毫秒级(ms)→ 慢 10万倍以上!

💡 解决方案:数据压缩

  • 数据变小了 → 读写的数据量减少 → I/O 减少 → 性能提升
  • 虽然压缩/解压要消耗 CPU,但 CPU 很快,这点开销值得

📈 二、压缩的好处(Trade-off:用 CPU 换 I/O)

“Data compression enables smaller database size, reduced I/O, and improved throughput, at the small cost of increased CPU utilization.”

✅ 压缩的三大收益:

好处说明
📉 更小的数据库体积磁盘占用减少,节省存储成本
🚀 更少的 I/O每次读写更少的数据块,尤其对随机读有利
📈 更高的吞吐量单位时间内能处理更多请求(TPS/QPS 提升)

⚖️ 代价:

  • 增加 CPU 使用率(压缩和解压需要计算)

📌 关键结论

只要你的 CPU 不是瓶颈,用 CPU 换 I/O 是非常划算的!


🔧 三、表压缩如何工作?—— 核心机制

1️⃣ 压缩页大小可以小于 innodb_page_size

“An InnoDB table created with ROW_FORMAT=COMPRESSED can use a smaller page size on disk than the configured innodb_page_size value.”

  • 默认 innodb_page_size = 16KB
  • 启用压缩后,磁盘上的页可以更小,比如 8KB、4KB、2KB、1KB
  • 小页 = 每次读写的数据更少 → I/O 更高效

📌 类比:

就像把一本书从“每页 1000 字”改成“每页 500 字”,找内容更快,翻页更轻量。


2️⃣ 如何设置压缩页大小?

通过 KEY_BLOCK_SIZE 参数:

CREATE TABLE t1 (...) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;  -- 目标压缩页大小为 8KB
  • KEY_BLOCK_SIZE目标压缩大小(单位 KB)
  • 实际是否能压缩到这个大小,取决于数据内容

📌 注意:

  • KEY_BLOCK_SIZE 必须 ≤ innodb_page_size / 2(即 ≤ 8KB)
  • 支持值:1, 2, 4, 8(KB)

3️⃣ 为什么必须用独立表空间?

“The table must be placed in a file-per-table tablespace or general tablespace… system tablespace cannot store compressed tables.”

  • 系统表空间(ibdata1)是共享的,管理复杂,不支持压缩页
  • 只有 独立表空间(每个表一个 .ibd 文件)通用表空间 支持压缩

✅ 所以只要 innodb_file_per_table=ON(默认开启),就可以用压缩。


📏 四、KEY_BLOCK_SIZE 的选择:不是越小越好!

“The level of compression is the same regardless of the KEY_BLOCK_SIZE value… But if you specify a value that is too small, there is additional overhead…”

✅ 重要理解:

  • KEY_BLOCK_SIZE 只是 目标大小,不是压缩率
  • 压缩算法(zlib)的压缩率是固定的,与 KEY_BLOCK_SIZE 无关

❗ 问题:设得太小会怎样?

如果 KEY_BLOCK_SIZE 太小(比如 1KB),但数据压缩后仍大于 1KB:

  • InnoDB 无法将多行数据塞进一页
  • 导致 页分裂(page split)频繁重组
  • 增加 CPU 和 I/O 开销,性能反而下降

🚫 硬限制:

  • KEY_BLOCK_SIZE 不能小于表中 所有索引键的总长度
  • 否则 CREATE TABLEALTER TABLE 会失败

📌 示例:

CREATE TABLE t1 (id BIGINT PRIMARY KEY,name VARCHAR(255),INDEX idx_name (name)
) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;

→ 可能失败,因为 name 索引键太长,1KB 放不下。


💾 五、内存中如何管理压缩页?—— Buffer Pool 的双重缓存

这是最关键的部分!

“In the buffer pool, the compressed data is held in small pages… MySQL also creates an uncompressed page…”

✅ 内存中的工作机制:

步骤说明
1️⃣ 读取数据从磁盘读取压缩页(如 8KB)→ 放入 Buffer Pool
2️⃣ 解压创建一个 16KB 的解压页(原始页大小)用于读取或修改
3️⃣ 使用所有 SQL 操作都在这个 解压页 上进行
4️⃣ 写回修改后,更新 压缩页,并标记为“脏页”
5️⃣ 淘汰当 Buffer Pool 不够时,解压页被释放,保留压缩页

🖼️ 图示:

Buffer Pool 内存:[ 压缩页 8KB ]  ←→  [ 解压页 16KB ]↑                   ↑磁盘存储           用于读写操作

⚠️ 对 Buffer Pool 的影响

  • 同一个数据,在内存中可能同时存在 压缩页 + 解压页
  • 占用更多内存
  • 需要 更大的 Buffer Pool 来避免频繁淘汰和重新解压

📌 但 MySQL 会智能管理:

  • 解压页是“临时”的,空间紧张时会被淘汰
  • 下次访问时再从压缩页重新解压

✅ 六、适用场景推荐

场景是否适合压缩
✅ 读多写少(如报表、历史数据)强烈推荐
✅ SSD 存储推荐(减少写放大,延长寿命)
✅ 大表、带索引的表推荐(索引也压缩)
✅ 内存充足推荐(能容纳更多数据)
❌ 高频更新的热表谨慎使用(CPU 和重组开销)
❌ 小表(< 100MB)不推荐(收益小)
❌ 已加密或二进制数据不推荐(难压缩)

✅ 总结:关键要点

要点说明
🔹 压缩目的用 CPU 换 I/O,提升性能
🔹 启用方式ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=N
🔹 支持条件必须是 file-per-table 或通用表空间
🔹 压缩页大小KEY_BLOCK_SIZE 控制(1/2/4/8KB)
🔹 不是越小越好太小会导致页重组,性能下降
🔹 内存机制Buffer Pool 同时缓存压缩页和解压页
🔹 Buffer Pool 需求可能需要更大内存
🔹 推荐场景读密集、SSD、大表、归档数据

💡 一句话建议

如果你的表大、读得多、磁盘是 SSD,且内存充足,启用表压缩(ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 是一个性价比极高的优化手段。但记得监控 CPU 和压缩效率,避免适得其反。

需要我帮你写一个 SQL 脚本,分析当前数据库中哪些表最适合启用压缩吗?

http://www.dtcms.com/a/414501.html

相关文章:

  • 做外贸网站需要缴什么税重庆高端网站建设价格
  • java面试day5 | 消息中间件、RabbitMQ、kafka、高可用机制、死信队列、消息不丢失、重复消费
  • 时序数据库选型指南:如何为企业选择合适的时序数据库解决方案
  • 【iOS】alloc、init、new
  • 做网站的开发心得wordpress是不是一定要买服务器
  • AI觉醒:小白的大模型冒险记 第10章:故事续写竞技场 - 实战演练
  • 网站的形成贵州省住房和城乡建设官方网站
  • python知识点
  • LeetCode 5.最长回文字符串
  • 浅谈蓝牙的连接基石
  • Matlab通过GUI实现点云的导向(引导)滤波(附最简版)
  • MacOS - Clang使用bits/stdc++.h - 非官方(竞赛用) - 通用方法
  • 智能进化:高端平板操控系统的技术革新
  • 网站开发专业职业规划微信小程序游戏开发教程
  • 中国工业互联网公司排名seo工程师是什么职业
  • 手机锁屏后WiFi流量/数据流量消耗的深层原因与解决方案
  • 使用 Entity Framework Code First 方法创建 ASP.NET Core 5.0 Web API
  • 网站建设前的分析公司概况了解google seo是什么啊
  • 【C++实战㊾】C++11新特性实战:nullptr与类型推导,解锁编程新姿势
  • Python笔记之Python中的`@`装饰器总结笔记
  • 存储器映射寄存器MMR(Memory-Mapped Register)
  • 【Big Data】DataX 3.0 星型数据链路架构的实践与价值
  • 芯片和半导体:三星发动2nm工艺价格战
  • NLP:讲解Bert模型的变体
  • wordpress成品站源码义乌网站建设九
  • 高通平台WiFi学习--- WLAN 进阶:无需开启 WiFi 也能使用 P2P 功能的实现与探索
  • 【论文笔记】基于深度学习的图像分割研究综述 和 基于深度学习的二分图像分割综述
  • 【足式机器人算法】#2 奖励函数设计
  • 机器人小脑的控制算法有哪些 ?
  • 网站程序上传教程wordpress 微媒体插件