一、问题触发场景
1. 背景:MySQL Bug: #112129。
2. 表中存在多个涉及重叠列的复合索引。
3. WHERE 包含大量 IN/NOT IN/OR 嵌套条件。
4. 触发了 Range Optimizer:SELECT、EXPLAIN SELECT、UPDATE、DELETE 等均可触发。
二、涉及问题的内核版本
MySQL 5.7全部内核版本。
三、修复的内核版本
MySQL 8.0 20201230及以上版本。
四、长期处理(推荐)
将内核版本升级至 MySQL 8.0 20201230或以上版本,操作方法请参考 升级 MySQL 5.7到 MySQL 8.0、升级内核小版本。
五、紧急处理
UNION ALL 拆分:将复杂的多层 OR 条件拆成多个简单子查询,用 UNION ALL 合并。每个子查询只包含 AND + IN 条件,不触发 key_or() 递归。
改写 SQL 参考:
SELECT C2 FROM( — 分支1: c6='V6' AND C4='25' AND C5 IN(…) AND c7='v7a' SELECT C2 FROM t1 WHERE C2 IS NOT NULL AND C2 <>'' AND C6 IN ('V6') AND C4='25' AND C5 IN ('1238','1296',…) AND C7 IN ('v7a') UNION ALL — 分支2: c4='4' AND C5 IN(…) SELECT C2 FROM t1 WHERE C2 IS NOT NULL AND C2 <>'' AND C4 ='4' AND 5 IN ('10135269','10144642') UNION ALL — 分支3: c4='20' AND C5 IN(…) SELECT C2 FROM t1 WHERE C2 IS NOT NULL AND c2 <>'' AND C4 ='20' AND C5 IN ('2000000085', '2000000086',…) UNION ALL — 分支4-7: NOT IN 分支,同理拆分 SELECT C2 FROM t1 WHERE C2 IS NOT NULL AND c2 <>'' AND C4 ='25' AND C5 NOT IN ('1238','1296',…) UNION ALL — …其他 NOT IN 分支 …) AS sub;