为何MySQL索引合并优化无Sort-Intersection算法?附案例咨询
问题解答
一、为什么不存在索引合并排序-交集(Sort-Intersection)算法?
索引合并的算法设计完全基于成本效率,Sort-Intersection没有存在的必要,原因如下:
- 索引合并交集(Intersection)的核心适用场景是:多个查询条件分别命中独立索引,且每个条件要么是等值匹配,要么是主键/唯一索引的范围匹配。这类场景下,各个索引返回的行ID(或主键值)本身就是有序的(因为索引结构是有序的),可以直接通过类似归并排序的方式高效计算交集,完全不需要额外排序。
- 如果真的出现需要先排序才能求交集的场景(比如两个普通索引的范围条件求交集),这种操作的成本会极高:要先分别扫描两个索引获取大量行ID,再对其中一组行ID排序,最后逐行比对求交集。这种方案的效率远不如直接走单索引范围查询后过滤,甚至不如全表扫描,MySQL优化器不会选择这种低效策略,因此也就没必要实现Sort-Intersection算法。
二、为什么select * from t2 where id>1000 and d<1000使用range查询而非索引合并?
你的SQL执行计划选择单索引range而非索引合并,本质是优化器成本评估的结果,具体原因:
- 索引合并交集的触发条件不满足
MySQL的Index Merge Intersection算法要求,多个AND连接的条件中,除了主键/唯一索引的范围条件外,其他条件必须是等值匹配。而你的SQL中d<1000是普通索引的范围条件,不符合这个触发规则,优化器不会考虑用索引合并交集。 - 单索引range的成本更低
执行计划显示走PRIMARY索引返回4973行,再过滤出d<1000的行(过滤率10.04%),这个流程的成本远低于模拟"Sort-Intersection"的操作:如果强行合并两个索引,需要先从idx_d取出所有d<1000的行ID(可能数量远大于4973),再排序这些行ID,最后和PRIMARY索引的行ID求交集,整个过程的IO和CPU成本都比单索引range+过滤高得多,优化器自然选择更高效的方案。
内容的提问来源于stack exchange,提问作者Jacky Zhao
相关产品推荐
相关产品推荐

