max_execution_time仅对select语句生效,作用于启用了查询优化器的存储引擎(如innodb),mysql 5.7.8+引入,需用/+ max_execution_time(毫秒) / hint置于select后,不支持insert...select、update、delete。

MAX_EXECUTION_TIME 在哪起作用?
它只对 SELECT 语句生效,且仅在启用了查询优化器的存储引擎(如 InnoDB)上有效;INSERT ... SELECT、UPDATE、DELETE 都不支持。MySQL 5.7.8+ 才引入这个 hint,低于该版本直接忽略。
怎么给单条查询加超时?
用 /*+ MAX_EXECUTION_TIME(1000) */ 这种 optimizer hint 放在 SELECT 关键字后面,单位是毫秒:
SELECT /*+ MAX_EXECUTION_TIME(500) */ name FROM users WHERE status = 1;
注意:MAX_EXECUTION_TIME 是 hint,不是 SQL 标准语法,不能写成函数调用或放在 WHERE 后;如果语句被重写(比如被代理或 ORM 自动加了括号),hint 可能失效。
如何让所有普通用户默认带超时?
靠全局变量 max_execution_time,但它只影响未显式指定 hint 的 SELECT:
- 设为
SET GLOBAL max_execution_time = 2000,新连接生效(老连接需重连) - 该值对 root 用户无效——root 绕过限制,普通用户才受控
- 如果某条
SELECT显式写了/*+ MAX_EXECUTION_TIME(0) */,就等于禁用超时,优先级高于全局设置
为什么有时候 timeout 不触发?
常见失效场景:
- 查询卡在锁等待(比如等
row lock),超时机制不介入,得靠innodb_lock_wait_timeout - 执行计划走全表扫描但数据量小,实际耗时低于阈值,不会中断
- 使用了
UNION或子查询,hint 只作用于最外层SELECT,内层不受控 - 客户端设置了
net_read_timeout,网络读取超时先于MAX_EXECUTION_TIME触发,看起来像“没生效”
真正难调试的是混合超时:锁等待、网络、执行时间三者边界模糊,得结合 SHOW PROCESSLIST 里 Time 和 State 字段一起看。











