You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL为何未使用notification_id_tag_value_recipient_brand联合索引?

为何MySQL未选用notification_id_tag_value_recipient_brand联合索引

1. 违背联合索引最左前缀原则

你的联合索引起始列为notification_id,但查询语句中完全没有涉及该列的过滤条件。MySQL联合索引遵循最左前缀匹配规则,必须从索引的第一列开始匹配才能有效利用索引,跳过起始列后,索引的有序性被破坏,无法发挥联合索引的过滤优势。

2. 联合索引列顺序与查询匹配效率低

即便忽略起始列,联合索引中tag_value位于第二列,recipient在第三列,brand在第四列。由于缺少notification_id的筛选,索引内的tag_value是分散在不同notification_id分组下的,此时用联合索引查找tag_value='doc1'的效率,远低于专门针对tag_value建立的单值索引——单值索引是完全按tag_value排序的,能快速定位目标数据。

3. brand条件的过滤成本高

查询中的(brand='brand' or brand is null)是多分支条件,且brand是联合索引的最后一列。在没有前面列(尤其是notification_id)精准匹配的前提下,MySQL需要在扫描到的tag_value和recipient匹配行中,额外过滤两种brand情况,这会增加索引扫描的计算成本。相比之下,用单值索引定位tag_value后,在内存中过滤recipient和brand的成本更低。

4. 优化器的成本评估结果

MySQL优化器会对比不同索引的使用成本,包括索引扫描行数、回表开销等。由于联合索引无法利用最左前缀,扫描的索引行数远多于单值索引,再加上后续过滤的额外成本,优化器最终选择了成本更低的tag_value单值索引。

如果希望查询使用联合索引,可以调整索引列顺序,例如创建tag_value, recipient, brand, notification_id这样的联合索引,让查询条件能匹配索引的最左前缀,从而充分利用联合索引的过滤能力。

内容的提问来源于stack exchange,提问作者Lakmal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:02:22