MySQL客户端开启压缩需显式启用:mysql命令加--compress、JDBC加useCompression=true、pymysql传compress=True;压缩仅对结果集生效,且受max_allowed_packet限制,高熵数据可能膨胀。

MySQL客户端开启压缩协议后没效果?检查mysql命令是否真用了--compress
很多用户以为加了--compress就自动压缩,实际mysql命令行工具默认不启用压缩,即使服务端have_compression为YES也无用。
-
mysql --compress -u root -p是显式启用;不带该参数,哪怕服务端支持,传输仍是明文未压缩 - Java应用需在JDBC URL里加
&useCompression=true,仅设serverTimezone等参数无效 - Python的
pymysql默认不压缩,得手动传compress=True;mysql-connector-python则需option_files或compress=True参数 - 压缩只对结果集生效(
SELECT返回的数据),INSERT/UPDATE语句本身不压缩
服务端max_allowed_packet太小会导致压缩失败并静默退化
启用压缩后,服务端需先解压再解析包。若原始压缩包解压后超过max_allowed_packet,MySQL会直接断开连接,错误日志里可能只写Lost connection to MySQL server during query,不提压缩。
- 建议把
max_allowed_packet设为压缩前预估最大结果的1.5倍以上,例如常查10MB文本字段,至少设16M - 动态修改:执行
SET GLOBAL max_allowed_packet = 16777216,注意单位是字节 - 该值不能超过服务端内存限制,
mysqld启动时若--max-allowed-packet=0会被忽略,必须给明确数值
不是所有数据都值得压缩——高熵内容反而增大体积
MySQL压缩用的是zlib,对已加密、已压缩(如JPEG/BLOB)、或随机性强的数据(如UUID、加密token)压缩率极低,甚至膨胀3–5%。
- 适合压缩:纯文本日志、JSON字段、HTML片段、重复度高的VARCHAR
- 不适合压缩:BASE64编码的二进制、
ENUM/SET字段(本身紧凑)、含大量空格/换行但无重复模式的字段 - 可在应用层判断:对大字段先做
LENGTH(json_field)和LENGTH(COMPRESS(json_field))对比,差值
压缩带来CPU开销,高并发下可能成为新瓶颈
压缩/解压由MySQL线程同步完成,单核CPU上100+并发查询压缩结果集时,top里mysqld的%CPU可能飙到90%,而网络带宽还没跑满。
- 监控关键指标:
SHOW STATUS LIKE 'Compression%'看Compression_rate是否稳定在0.3–0.6;低于0.2说明收益小,高于0.8说明压缩过度(可能数据异常) - 线上建议先对慢查询或大分页接口(如
LIMIT 10000,20)单独启用压缩,避免全局打开 - 如果服务器是ARM架构(如AWS Graviton),zlib性能比x86弱约20%,压缩阈值要更保守


















