SELECT id FROM orders WHERE user_id = 7
UNION
SELECT id FROM orders WHERE order_no = 'A100';

查询写成 WHERE user_id = 7 OR order_no = 'A100',explain 里 type 是 index_merge,rows 合起来 40 万,实际耗时 1.9 秒。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:or 两边是不同字段时,优化器要么做索引合并要么整表扫,索引合并还要把两个结果集去重排序。任一列选择性差,合并出来的行数就下不来。

这次卡住的地方就在「or 条件索引」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

处理上按这个顺序:把 or 拆成两条查询 在应用层合并去重;确认两个字段都有独立索引 缺一个就会退化成全表;业务允许的话改成 union 再在外层去重;用 explain 看是否还在走 index_merge。

确认没问题再收工,两条子查询各自走索引 合并后耗时降到几十毫秒 结果集和原来一致。

作者 9823189