mysql最左前缀原则怎么理解_mysql联合索引原理

7次阅读

联合索引是一棵 B + 树而非多个索引,按定义列顺序排序,必须遵循最左前缀原则才能有效使用;范围查询列应置于联合索引末尾,且需通过 EXPLAIN 验证 key 和 key_len 字段确认索引实际使用情况。

mysql 最左前缀原则怎么理解_mysql 联合索引原理

联合索引不是多个索引,而是一棵 B + 树

很多人误以为 CREATE INDEX idx_a_b_c ON t(a,b,c) 会生成 (a)(a,b)(a,b,c) 三棵树——其实不会。MySQL 只建一棵 B + 树,排序规则是:先按 a 升序,a 相同时再按 b 升序,ab 都相同时再按 c 升序。这就决定了查询必须“从左开始连续匹配”,否则无法定位到有序区间。

  • 能用索引:WHERE a = 1WHERE a = 1 AND b = 2WHERE a = 1 AND b = 2 AND c > 10
  • 不能用索引:WHERE b = 2(跳过 a)、WHERE a = 1 AND c = 3b 中断,c 无法继续走索引)
  • 注意:WHERE b = 2 AND a = 1 看似顺序反了,但 MySQL 查询优化器会自动重排为 a = 1 AND b = 2,仍可命中索引

范围查询(>、

这是最常踩的坑。一旦联合索引中某列用了范围条件,它右边所有列就 ** 彻底失去索引加速能力 **,哪怕你写了等值条件也不行。

SELECT * FROM orders WHERE user_id = 1001 AND status = 1 AND create_time > '2024-01-01';

这句只能用上 (user_id, status)create_time 的范围判断之后,索引就“断”了——即使你后面还加了 AND pay_amount = 99.9,这个 pay_amount 也查不到索引。

  • 正确做法:把范围列尽量放在联合索引末尾,如 (user_id, status, create_time)
  • 错误设计:若常用 WHERE status = 1 AND create_time BETWEEN …… AND ……,却把 status 放在第二位,那这个查询根本用不上索引
  • LIKE 'abc%' 是范围行为,LIKE '%abc' 则完全不走索引(连最左都不满足)

explain 是唯一能验证你是否真用上索引的 工具

别靠“我写了 where a=1 and b=2”就以为索引生效了。必须看 EXPLAINkeykey_len 字段:

  • key 显示实际使用的索引名 → 确认没走全表扫描
  • key_len 显示用了索引多少 字节 → 比如 idx_user_status_timeuser_id 是 INT(4 字节),status 是 TINYINT(1 字节),那么 key_len = 5 表示只用到了前两列;若 key_len = 4,说明只用到了 user_idstatus 没参与索引查找
  • 执行 EXPLAIN FORMAT=TRADITIONAL SELECT ……,重点关注 type(最好为 refrange),避免出现 ALL

索引字段顺序不是“哪个查得多就放前面”,而是按查询模式定

有人觉得“status 取值少、区分度低,应该放后面”,但现实是:如果你的高频查询是 WHERE status = 'paid' AND user_id IN (1,2,3),那这个索引 (status, user_id) 就比 (user_id, status) 更合适——因为前者能直接定位到所有 status='paid' 的数据块,再在其中快速筛选 user_id;后者却要先遍历每个 user_id 对应的索引项,再回表判断 status,效率反而更低。

  • 等值查询多、范围查询少 → 把高选择性(区分度高)字段放前面
  • 固定前缀 + 范围查询 → 把等值列全放左,范围列放右,如 (shop_id, category_id, created_at)
  • 存在多个高频查询组合?优先覆盖最耗性能的那条,或拆成两个索引(空间换时间)

真正容易被忽略的是:最左前缀原则不是“语法限制”,而是 B + 树物理结构决定的刚性约束。写 SQL 时字段顺序无关紧要,但索引定义的列序一旦定下,就锁死了所有可能的查询路径。改索引成本远高于改 SQL,所以建之前就得想清楚主查询模式。

星耀云
版权声明:本站原创文章,由 星耀云 2025-12-29发表,共计1597字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources