含Order By与OR子句的多列索引不生效问题求解
索引未生效的原因
- 不符合联合索引最左前缀匹配规则:你创建的两个多列索引均将
ticket_type_order作为首列,但你的查询WHERE条件中没有对ticket_type_order的过滤逻辑,优先使用的是event_id、active两个等值过滤条件,数据库无法通过索引首列快速缩小数据范围,因此不会选择这两个索引。 - 索引列顺序与查询逻辑不匹配:联合索引的过滤优先级是从左到右,等值过滤条件需要排在索引前列才能生效,你现有索引把排序列放在过滤条件之前,顺序完全倒置,就算强制走索引,效率也低于全表扫描,数据库优化器会自动放弃。
- OR条件无有效索引支撑:现有两个索引中,OR逻辑涉及的
is_unlimited、number_of_sold_tickets、number_of_tickets的排列顺序不符合过滤逻辑,无法高效完成OR条件的过滤判断。
适配查询的索引调整方案
建议创建如下联合索引:
CREATE INDEX idx_ticket_event_active_order ON ticket_type (event_id, active, ticket_type_order, is_unlimited, number_of_sold_tickets, number_of_tickets)
设计逻辑说明:
- 前两列
event_id、active为查询中的等值过滤条件,放在索引最左侧符合最左前缀规则,可快速定位符合基础过滤条件的数据集。 - 第三列为排序字段
ticket_type_order,定位到的数据集已经按该字段顺序排列,无需额外执行文件排序(filesort)操作,大幅提升排序效率。 - 后续追加OR条件涉及的三个字段,可直接在索引内完成OR逻辑的过滤判断,若业务允许将
select *替换为具体需要的字段,该索引可直接作为覆盖索引使用,完全避免回表查询。
内容的提问来源于stack exchange,提问作者Arvind Choudhary
相关产品推荐
相关产品推荐

