InnoDB表级压缩需Barracuda格式+ROW_FORMAT=COMPRESSED+KEY_BLOCK_SIZE,压缩数据页而非整表或列;网络压缩(--compress)不减磁盘空间;字段级压缩用COMPRESS()/UNCOMPRESS()函数。

MySQL 表级压缩:InnoDB 的 ROW_FORMAT=COMPRESSED 怎么用
直接结论:InnoDB 支持表级压缩,但仅限于使用 Barracuda 文件格式 + ROW_FORMAT=COMPRESSED,且必须配合 KEY_BLOCK_SIZE 设置(如 1、2、4、8、16,单位 KB)。它压缩的是每个数据页(16KB),不是整张表或列。
常见错误是建表时只写 ROW_FORMAT=COMPRESSED 却没设 FILE_FORMAT=Barracuda 或忽略 innodb_file_per_table=ON —— 这会导致语句静默退化为 ROW_FORMAT=Dynamic,完全不压缩。
-
innodb_file_format在 MySQL 5.7.7+ 已废弃,实际由innodb_file_per_table和表空间类型决定;务必确认SHOW VARIABLES LIKE 'innodb_file_per_table';返回ON - 建表示例:
CREATE TABLE t1 (id INT, data TEXT) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
- 已存在表需重建:
ALTER TABLE t1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;,注意这会锁表并产生临时空间 - 压缩效果高度依赖数据重复度和长度;短文本或随机二进制(如加密字段)几乎不减小体积,反而因页管理开销略增
MySQL 服务端压缩传输:mysql --compress 和 my.cnf 中的 compress
这个「压缩」跟存储成本无关,只压缩客户端与服务端之间的网络包,节省带宽,不减少磁盘占用。很多人误以为开了它就能省存储,其实完全不影响 .ibd 文件大小。
启用方式有两种:
- 连接时加参数:
mysql --compress -u user -p db_name - 配置文件中设置:
[client]\ncompress=1
(注意是[client]段,不是[mysqld]) - 服务端需支持:MySQL 5.7+ 默认允许,但若
skip-networking=1或启用了require_secure_transport,可能被禁用 - 性能影响:CPU 占用略升,延迟在千兆内网可忽略;WAN 环境下对大结果集(如
SELECT * FROM huge_log)有明显提速
列级压缩:用 COMPRESS() + UNCOMPRESS() 手动处理 BLOB/TEXT 字段
这是真正可控、按需压缩单个字段的方式,适合存日志、JSON、HTML 等长文本。压缩发生在应用层或 SQL 层,数据以 VARBINARY 形式落地,节省磁盘空间明确。
但必须自己管理压缩/解压逻辑,ORM 或查询工具不会自动识别:
- 插入时压缩:
INSERT INTO logs (content) VALUES (COMPRESS('very long string...')); - 查询时解压:
SELECT UNCOMPRESS(content) FROM logs WHERE id = 1; - 不能对压缩后的字段建普通索引;若需搜索,得额外存摘要(如
SUBSTR(content, 1, 200))或用生成列 + 虚拟索引 - 注意返回值:
COMPRESS()失败(如内存不足)返回NULL,且不报错;建议在应用层加校验 - MySQL 8.0.19+ 支持
ZSTD压缩算法(需编译支持),比默认的zlib压缩率更高、速度更快,但需显式调用COMPRESS(..., 'zstd')
真正影响存储成本的关键点:别只盯压缩,先看行格式和页利用率
很多用户花时间调 KEY_BLOCK_SIZE,却发现表体积没怎么变——问题往往出在原始数据太稀疏或行太小。InnoDB 压缩是以页为单位的,如果一行就占满一页(比如含多个大 TEXT),压缩无效;反之,若一行只有几十字节,一页能塞上百行,压缩收益才明显。
更值得优先检查的项:
- 是否用了
TEXT/BLOB导致行溢出?溢出页不参与COMPRESSED页压缩,它们始终以未压缩形式存在 - 字符集是否过大?
utf8mb4下一个 emoji 占 4 字节,而latin1下纯英文字段可省 3/4 空间 —— 压缩前先精简编码更有效 - 有没有大量
NULL值?InnoDB 对NULL本身不存数据,但若定义了默认值或频繁UPDATE设为非 NULL,会引发页分裂和碎片 -
innodb_page_cleaner和innodb_adaptive_hash_index等参数虽不直接影响体积,但会影响压缩页的刷盘效率和缓存命中,间接决定“压缩后是否真快”
压缩不是银弹;它把 CPU 换成磁盘,还可能让随机读变慢。上线前务必在真实数据量和 QPS 下压测 IO 和 CPU 使用率。










