mysql联合索引怎么用才正确_mysql索引规则解析

6次阅读

联合索引仅支持最左前缀匹配:a=1、a=1 AND b=2、a=1 AND b=2 AND c= 3 可走索引;b= 2 或 a =1 AND c= 3 则无法充分利用。字段顺序应按选择性与查询模式排列,高区分度字段靠左,排序字段靠右。

mysql 联合索引怎么用才正确_mysql 索引规则解析

联合索引能用上的查询条件长什么样?

只有满足「最左前缀匹配」的 WHERE 条件,才能真正走 INDEX(a, b, c) 这类联合索引。不是“包含这些字段就行”,而是必须从最左边开始、连续使用。

  • a = 1 ✅ 走索引(只用 a)
  • a = 1 AND b = 2 ✅ 走索引(a + b)
  • a = 1 AND b = 2 AND c = 3 ✅ 走索引(全列匹配)
  • b = 2 ❌ 不走索引(跳过了 a)
  • a = 1 AND c = 3 ❌ 只用上 a,c 被跳过,b 没参与 → b 字段无法利用索引排序,c 实际失效
  • a IN (1,2) AND b = 3 ✅ 走索引(IN 算等值,仍满足最左前缀)

注意:MySQL 查询优化器会自动调整 WHERE 子句中字段顺序(比如把 b = 2 AND a = 1 改成 a = 1 AND b = 2),但前提是所有字段都在同一层级且无函数 / 计算干扰 —— 别依赖它来“救场”,自己写对才是稳的。

联合索引字段顺序怎么排才不翻车?

顺序不是按字母或出现频率排,而是按「选择性」和「查询模式」定:高区分度字段放前面,高频过滤字段靠左,排序 / 分组字段尽量靠右。

  • 错误示例:INDEX(gender, age) —— gender 只有男 / 女,索引树第一层就分裂成两支,后续 age 再怎么细分也意义不大
  • 正确示例:INDEX(age, gender) —— 先按年龄精细切分,再在每个年龄段里筛性别,B+ 树搜索路径更短
  • 如果常查 WHERE user_id = ? ORDER BY create_time DESC,优先建 INDEX(user_id, create_time),而不是分开两个单列索引

验证选择性:可用 SELECT COUNT(DISTINCT col)/COUNT(*) FROM table 粗估;值越接近 1,该列越适合作为联合索引首列。

为什么 加了联合索引,EXPLAIN 还显示 type=ALL 或 Using filesort?

EXPLAINtype=ALL 表示全表扫描,Extra: Using filesort 表示 MySQL 没法用索引完成排序 —— 这两类问题往往不是没建索引,而是索引没被“完整驱动”。

  • WHERE a = 1 ORDER BY b + INDEX(a, b) ✅ 能避免 filesort
  • WHERE a = 1 ORDER BY c + INDEX(a, b, c)c 不在索引前缀连续段内,无法利用排序结构,仍 filesort
  • SELECT * FROM t WHERE b = 2 + INDEX(a, b, c) ❌ 最左没匹配,直接退化为全表扫
  • WHERE a = 1 AND b > 10 ORDER BY c + INDEX(a, b, c) ⚠️ b 是范围查询,c 的排序失效(B+ 树中,a 相同、b > 10 的 c 值是无序的)

关键点:范围查询(>, , BETWEEN, LIKE 'abc%')之后的字段,只能用于索引查找,不能用于排序或精确匹配。

什么时候该用联合索引,而不是多个单列索引?

当你的高频查询同时命中多个字段,且存在固定组合时,联合索引几乎总是优于多个单列索引 —— 因为 MySQL 一般一次只用一个索引(除非开启 index_merge,但代价高、不可控)。

SELECT * FROM orders WHERE user_id = 123 AND status = 'paid' AND created_at > '2025-01-01';
  • 错:分别建 INDEX(user_id)INDEX(status)INDEX(created_at) → 优化器大概率只选一个,其余条件回表过滤,慢
  • 对:建 INDEX(user_id, status, created_at) → 三条件一次性定位,且若只查这三列,还能覆盖索引(Extra: Using index
  • 更优:如果 status 只有 3–4 个值,而 user_id 是主键级区分度,就把 user_id 放最左;再根据实际数据分布微调

别忘了删冗余索引:比如已有 INDEX(a, b, c),再单独建 INDEX(a)INDEX(a, b) 就是浪费 —— 写入开销白增,优化器还可能选错。

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