MySQL升级后子查询变慢主因是优化器处理逻辑变更,需用optimizer_trace分析决策过程:先确认其开启且内存充足,再聚焦join_preparation和join_optimization阶段的转换与物化选择,并比对升级前后optimizer_switch中semijoin、materialization等开关差异。

MySQL升级后子查询变慢,大概率不是子查询本身有问题,而是优化器对子查询的处理逻辑变了——optimizer_trace 能直接看到它“想”怎么执行、为什么放弃某个索引、为什么把子查询转成物化表或半连接,比 EXPLAIN 多一层决策依据。
子查询执行路径突变,先看 optimizer_trace 是否开启并生效
很多人以为开了 optimizer_trace 就万事大吉,其实常踩两个坑:
-
optimizer_trace默认是enabled=off,且只对**当前会话**生效,新开连接要重设 - 执行完目标 SQL 后必须立刻查
information_schema.optimizer_trace,否则下一条语句会覆盖上一条的 trace 记录 - 如果 trace 输出里
MISSING_BYTES_BEYOND_MAX_MEM_SIZE > 0,说明关键决策段被截断了,得调大optimizer_trace_max_mem_size(比如设为1000000)
确认方式:
SET SESSION optimizer_trace = "enabled=on", optimizer_trace_max_mem_size = 1000000; SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE status = 'active'); SELECT * FROM information_schema.optimizer_trace\G
从 trace JSON 里快速定位子查询劣化点
不用通读整个 JSON,盯住这几个字段就行:
-
join_preparation阶段:看子查询是否被标记为select#2,以及是否出现"transformations_to_child_items": ["IN_TO_EXISTS"]—— 这表示优化器尝试把IN转成EXISTS,但可能失败了 -
join_optimization阶段:重点找"chosen": true的物化(materialization)或半连接(semijoin)分支。若旧版走的是semijoin,新版却 fallback 到materialization+ 临时表,性能就容易崩 -
"rows_estimation"下各表的rows预估:若子查询表的预估行数从几千跳到几百万,说明统计信息没更新,优化器误判了选择性
典型劣化信号:
"transformation": "subquery_materialization_cost_based", "cause": "cost of materialization less than cost of subquery evaluation"
对比升级前后 optimizer_trace,重点关注 optimizer_switch 变动
MySQL 5.7 升级到 8.0 后,semijoin、materialization、loosescan 这几个子查询相关开关默认值全变了。不比对就瞎调,容易越调越慢。
- 执行
SELECT @@optimizer_switch;,搜关键词semijoin、materialization、loosescan - 5.7 常见配置:
semijoin=on,materialization=on,loosescan=on - 8.0 默认可能变成:
semijoin=off,materialization=off(尤其在低内存或高并发场景下自动关闭) - 临时验证:在会话中执行
SET optimizer_switch='semijoin=on,materialization=on';,再跑一遍子查询看 trace 是否回归原路径
子查询慢不是只能靠 optimizer_trace,但它是唯一能解释“为什么”的工具
EXPLAIN 只告诉你“它用了什么”,optimizer_trace 才告诉你“它为什么选这个、放弃了哪些、成本算出来差多少”。升级后子查询劣化,往往卡在优化器对嵌套层级、物化开销、索引下推的重新评估上——这些判断藏在 trace 的 condition_processing、range_analysis、attaching_conditions_to_tables 等节点里。漏掉其中任一环,都可能把问题归咎于索引或数据量,而实际是优化器“想错了”。


















