答案是max_execution_time,因为wait_timeout仅控制空闲连接断开,对正在执行的查询无效;而max_execution_time(MySQL 5.7.8+)可主动中断超时的SELECT语句,单位毫秒,支持SQL提示、会话级或全局设置。

不能只靠 wait_timeout 或 interactive_timeout 控制长查询执行流程——它们管的是“空闲连接”,不是“正在跑的查询”。真正能中断慢查询的,是 max_execution_time。
为什么 wait_timeout 对长查询无效
wait_timeout 只在连接处于空闲状态(即没有 SQL 正在执行、也没有结果正在返回)时倒计时。只要一个 SELECT 语句还在执行中,哪怕跑了 10 分钟,wait_timeout 完全不触发。
常见误解是:调低 wait_timeout = 30 就能“杀掉慢查询”。实际效果是——查询跑完前不会断,但查完后如果没立刻发新请求,30 秒后连接被服务端主动关闭,下次请求就得重连。
- 适用场景:防止应用忘记 close() 导致大量 sleeping 连接堆积
- 不适用场景:阻止单条耗时过长的
SELECT、UPDATE或INSERT ... SELECT - 副作用:设得太低(如 60 秒)可能让批量导入、报表导出类任务反复断连重试
用 max_execution_time 中断运行中的查询
max_execution_time 是 MySQL 5.7.8+ 引入的会话级参数,单位毫秒,对 SELECT 语句生效(部分版本也支持 INSERT/UPDATE,取决于 optimizer_switch 设置)。
它会在查询执行时间超过阈值时,由服务器主动终止该语句,并返回错误:Query execution was interrupted, maximum execution time exceeded。
- 全局设置(影响所有新会话):
SET GLOBAL max_execution_time = 30000;(30 秒) - 会话设置(更安全,推荐):
SET SESSION max_execution_time = 15000;(15 秒),可在业务逻辑前执行 - SQL 级覆盖(最细粒度):
SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM orders WHERE ...; - 注意:该参数对存储过程内部的 SELECT 不生效,也不影响 DDL(如
CREATE TABLE AS SELECT)
connect_timeout 和 net_read_timeout 的真实作用
这两个参数常被误认为能“限制查询时间”,其实它们控制的是网络握手与数据传输阶段:
-
connect_timeout:客户端发起 TCP 连接后,MySQL 服务端接受并完成 SSL/TLS 握手的等待上限。若设为 5 秒,而网络延迟高或服务端忙,就会报Lost connection during handshake。建议生产环境设为10~15 -
net_read_timeout:服务端从客户端读取下一个数据包(比如预处理语句的参数、流式结果的下一批)的等待时间。对长查询本身无影响,但会影响大结果集分批拉取时的稳定性。慢网络下可设为120~300 - 二者都不参与 SQL 执行逻辑判断,不会中断已开始执行的语句
连接池配置必须匹配数据库超时
即使数据库侧设置了 max_execution_time = 30000,如果连接池的 connectionTimeout(如 HikariCP 的 connection-timeout)设为 3000 毫秒(3 秒),那还没等 SQL 执行到 30 秒,连接池就先报“无法获取连接”了。
关键对齐点:
-
maxLifetime必须小于wait_timeout(例如wait_timeout = 600→maxLifetime = 540000ms) -
connectionTimeout应略大于connect_timeout(例如connect_timeout = 10→connectionTimeout = 12000ms) -
validationTimeout和testOnBorrow要启用,否则可能拿到已被服务端关闭的连接
最容易被忽略的是:应用层捕获到 max_execution_time 触发的中断错误后,往往直接重试——而重试的 SQL 依然会再次超时,形成死循环。必须结合业务逻辑判断是否降级、缓存 fallback 或记录告警。


















