thread_cache_size通过缓存空闲线程复用,避免频繁创建/销毁开销,降低短连接延迟0.5–2ms;需配合wait_timeout、应用层主动close及系统限制协同生效。

thread_cache_size 为什么能降低连接开销
MySQL 每个新连接都需要分配一个线程,创建/销毁线程本身有 CPU 和内存开销。设了 thread_cache_size 后,客户端断开时线程不销毁,而是放进缓存池;下次新连接进来,直接复用空闲线程,跳过初始化流程——省掉约 0.5–2ms 延迟(实测常见于短连接密集场景)。但这个机制只在「连接主动关闭」且「缓存未满」时生效;如果 thread_cache_size = 0(默认值之一),每次连接都新建线程,Threads_created 会肉眼可见地飙升。
怎么判断当前 thread_cache_size 是否起作用
别猜,查状态变量:
-
SHOW STATUS LIKE 'Threads_created';—— 如果每秒增量 > 1~2,说明线程频繁重建,缓存大概率没生效 -
SHOW STATUS LIKE 'Threads_cached';—— 长期为 0 或始终卡在极低值(如 0/1),基本等于没缓存 -
SHOW STATUS LIKE 'Threads_connected';—— 如果剧烈波动(比如 3 → 180 → 5),大概率是应用没调conn.close(),不是配置问题 -
SHOW VARIABLES LIKE 'wait_timeout';—— 若 ≤ 30,线程刚进缓存几秒就被踢出,缓存形同虚设
thread_cache_size 设多少才实际有效
没有固定公式,看反馈调:
- 短连接为主(如 PHP-FPM、无连接池的 Python 脚本):起步设
thread_cache_size = 16,观察Threads_cached是否稳定在 8~12;若长期卡在 16,可试 24 - 已用连接池(如 HikariCP、Druid):
thread_cache_size = 4~8足够,再大无意义,因连接数被池控住,MySQL 线程复用压力小 - 别盲目堆高:超过 CPU 核心数 × 2(比如 32 核机器设到 64)后,命中率几乎不涨,每个空闲线程还占 256KB~1MB 内存,
Threads_cached = 64就可能吃掉 64MB+ - 必须同步检查
max_connections:如果SHOW STATUS LIKE 'Aborted_connects';持续增长,说明大量连接连认证都失败,加缓存纯属白忙
设了却没效果?先排查这三类硬伤
90% 的“设了没用”不是参数问题,而是环境或客户端行为卡住了缓存链路:
- 应用层没主动 close 连接(Java 忘写
conn.close()、Python 忘cursor.close()或conn.close()),MySQL 收不到 FIN 包,线程直接销毁,不进缓存 - 中间件(HAProxy/Nginx)开了 TCP keepalive 却没透传 FIN,MySQL 认为连接还活着,既不释放也不缓存
- 系统级限制挡路:
ulimit -n太小、net.core.somaxconn不足,导致 MySQL 根本创建不出足够线程,thread_cache_size再大也无从缓存
真正卡在 200ms 左右抖动?大概率是 thread_cache_size 不足 + wait_timeout 过短的组合问题——线程刚缓存下来,几秒后就被清掉,下个请求又得重建。这时候调参不如先看连接生命周期是否闭环。


















