已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
我负责一套 MySQL 8.0.32(InnoDB,主从架构,核心库 8 张表、总数据量约 3 亿行)的日常运维。最近一次 minor 升级(8.0.32 → 8.0.36)后,业务侧反馈「部分报表 SQL 变慢了」,我拉了慢日志对比,发现同一批 SQL 的执行计划确实发生了变化:
t_a → t_b → t_c → t_d 变成了 t_b → t_a → t_d → t_c,P95 从 200ms 涨到 1.8s;idx_tenant_time (tenant_id, created_at) 的查询,升级后改走了全表扫描(表约 5000 万行);GROUP BY 查询,升级后从 Using index for group-by 变成了 Using temporary; Using filesort。我理解 8.0.32 → 8.0.36 之间优化器有多次改动(hash join 默认开启、derived condition pushdown 行为调整、histogram 采样策略变化等),所以执行计划变化不算「bug」,但我缺一套系统性的回归验证流程,目前只能:
EXPLAIN 对比升级前后的计划(核心 SQL 有 60+ 条,肉眼对比效率极低且容易漏);optimizer_switch 或加 hint 回退(治标不治本,下次升级还得再来一遍);ANALYZE TABLE 重新收集统计信息,部分 SQL 恢复了,但 JOIN 顺序那条还是没回来。具体卡点:
performance_schema 抓升级前的 SQL 指纹 + 计划,升级后回放对比?或者用 mysql_test / 自研 SQL 回放工具跑「计划指纹 diff」?ANALYZE TABLE?histogram 是自动重建还是手动 ANALYZE TABLE ... UPDATE HISTOGRAM?8.0.36 的 histogram 采样算法和 8.0.32 有差异吗?optimizer_switch 项在 8.0.32→8.0.36 之间行为发生了变化?有没有官方 changelog 里明确标注「plan-affecting」的改动清单?EXPLAIN FORMAT=JSON 做 diff,或用 optimizer_trace 抓决策路径)?ANALYZE TABLE 全库跑了一遍,3 条 SQL 恢复了,JOIN 顺序那条没恢复;STRAIGHT_JOIN,性能恢复了但语义上锁死了 JOIN 顺序,后续表结构变化可能再出问题;希望有同学能给出:
如果你们最后选择「不升 minor,只升 patch」或「升级后靠 optimizer_switch 逐条回退」,也请说下原因和代价,我这边好权衡。