用同一份高重复度文本,各建一张压缩表和不压缩表,对比它们在磁盘上真实的文件大小差多少。
代码CREATE TABLE comp_test (id INT PRIMARY KEY AUTO_INCREMENT, txt TEXT) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; CREATE TABLE uncomp_test (id INT PRIMARY KEY AUTO_INCREMENT, txt TEXT) ROW_FORMAT=DYNAMIC; -- 两张表真实各插入100行,每行都是同一句英文重复50次拼出来的长文本
comp_test.ibd(ROW_FORMAT=COMPRESSED): 172032 字节 (168KB) uncomp_test.ibd(ROW_FORMAT=DYNAMIC): 393216 字节 (384KB) 真实压缩比 ≈ 2.28倍
两张表存的是完全相同的数据,唯一的区别是ROW_FORMAT=COMPRESSED加上KEY_BLOCK_SIZE=8——这告诉InnoDB把标准的16KB页面,压缩后目标存进8KB的物理块里。本文这次测试用的文本重复度极高(同一句话重复50次),真实的压缩效果会比典型业务数据(比如JSON、二进制)好得多,2.28倍这个具体数字不能直接套用到别的数据上,但页面压缩确实真实能省下可观的磁盘空间,代价是读写这些页面时CPU真实要多做一道压缩/解压的工作。
KEY_BLOCK_SIZE真实指定的是压缩后每个页面尝试塞进多大的物理块(本文用了8KB,可选值通常是1/2/4/8/16KB),不是一个压缩率参数——如果实际数据压缩之后还是装不进这个目标大小,InnoDB会真实把这个页面拆成两个更小的页面重新压缩,这个过程叫"压缩页分裂",真实是额外的开销来源。真实要不要用页面压缩,取决于两件事的权衡:数据本身的可压缩程度(文本类数据通常比已经压缩过的二进制数据效果好得多),以及愿不愿意用CPU开销去换磁盘空间——这在CPU相对充裕、磁盘I/O是瓶颈的场景下真实是划算的。
每一步都是本文上面用真实磁盘文件大小跑出来的原始结果。