联合索引是按顺序排好序的

用最简单、最形象、最不绕弯 的方式给你讲懂!

你现在卡住的点,90%的人都在这里懵,我一句话先点破:

超级核心结论(你必须先记住)

**联合索引是按顺序排好序的:

只有前面字段 完全确定(=) ,后面字段才是 有序的

一旦前面出现 范围(> <) ,后面字段 立刻乱序 → 索引失效!


我给你用【字典法】讲,你瞬间就懂!

联合索引 (a,b,c) 排序规则:

先按 a 排序 → 再按 b 排序 → 再按 c 排序

只有前面是"=",后面才是排好序的!


情况1:你能懂的

a=1 and b=2 and c>3

索引结构是这样排好序的:

复制代码
a=1固定
  b=2固定
    c=3 ✔
    c=4 ✔
    c=5 ✔

因为 a 固定、b 固定

所以 c 是排好序的

所以 c>3 可以用索引!


情况2:你现在不懂的(重点来了!)

a=1 and b>2 and c in (1,2)

索引结构是这样的:

复制代码
a=1固定
   b=3 → c 排序是:1,2,4,5
   b=4 → c 排序是:2,1,5,3
   b=5 → c 排序是:5,2,1,4

重点来了:
b 是范围(>2)→ b 有很多值(3、4、5...)
每个 b 对应的 c 都是
分开排序、整体乱掉的!**

所以:

c 无法再用索引!


我用一句人话总结

前面是 = → 后面有序 → 索引能用
前面是 > → 后面乱序 → 索引失效


回到你的问题:

1. 为什么 a=1 and b>2 and c in(1,2)

b 能命中,c 不能命中?

因为:

  • a=1 固定
  • b>2 是范围,但 b 自己还是有序的 → 能用到索引
  • b 范围导致 c 乱序 → c 不能用索引

2. 为什么 a=1 and b=2 and c>3

c 能命中?

因为:

  • a 固定
  • b 固定
  • c 自然有序 → 可以用索引

最终最精炼口诀(背这个就够了)

前面等值,后面有序;
前面范围,后面乱序;
范围一断,后面全断!


面试标准答案(你直接背)

联合索引(a,b,c)是有序结构,只有前面字段是等值(=)时,后面字段才是有序的。

  • a=1 and b=2 and c>3

    a、b 都是等值,c 有序,所以 c 能命中索引

  • a=1 and b>2 and c in(1,2)

    b 是范围查询,导致 c 变成无序,索引失效,c 无法命中

范围列会中断后面所有索引字段,无论后面是 in 还是 = 都无效。


结合联合索引有序存储的本质,用分组图示+分步拆解,彻底讲透两种场景,看完就通。

联合索引 (a,b,c) 底层存储逻辑:先按a排序,a相同再按b排序,b相同再按c排序 ,整条索引树是全局有序的。


场景1:a=1 and b=2 and c>3

条件:a=1(等值)b=2(等值)c>3(范围)

索引数据分组

复制代码
a=1
└── b=2
    ├── c=1
    ├── c=2
    ├── c=3
    ├── c=4
    ├── c=5
    └── c=6
  1. a=1:精准定位到 a=1 这一大组 ✅ 命中索引
  2. b=2:在 a=1 组内,精准定位到 b=2 小组 ✅ 命中索引
  3. 此时整个小组内的 c 是连续有序排列 ,数据库可以直接在索引上筛选 c>3
    c 也能命中索引

✅ 最终:a、b、c 三个字段全部走索引


场景2:a=1 and b>2 and c in (1,2)

条件:a=1(等值)b>2(范围)c in(1,2)(等值)

索引数据分组

复制代码
a=1
├── b=3          ← 满足 b>2
│   ├── c=5
│   ├── c=1
│   ├── c=4
│   └── c=2
├── b=4          ← 满足 b>2
│   ├── c=2
│   ├── c=3
│   └── c=1
└── b=5          ← 满足 b>2
    ├── c=4
    ├── c=1
    └── c=3
  1. a=1:精准定位到 a=1 大组 ✅ 命中索引
  2. b>2:在 a=1 组内,筛选出 b=3、4、5 等数据
    • b 自身是有序的 ,所以 b 可以正常走索引 ✅ 命中索引
  3. 关键问题:
    b范围匹配 ,会命中多个不同的b值
    每一个 b 内部的 c 虽然局部有序,但跨b之后,c整体完全乱序
    数据库无法利用索引规则快速筛选 c in (1,2),只能遍历数据过滤。
    c 无法命中索引

✅ 最终:仅 a、b 两个字段走索引,c 索引失效


核心规则总结(记这2句)

  1. 范围字段本身可以使用索引 ,但范围字段之后的所有字段,索引全部中断
  2. 中断和后面是 =in> 无关,只要前面出现范围,后面字段都无法走索引检索(仅能靠索引下推做数据过滤)。

对比复盘(对应你两个疑问)

查询语句 索引命中字段 原因
a=1 and b=2 and c>3 a、b、c a、b 都是等值,c 保持全局有序,范围查询可走索引
a=1 and b>2 and c in(1,2) a、b b 是范围,导致后续 c 整体乱序,索引中断

面试标准口述版

联合索引遵循顺序排序规则,字段依次有序排列。

  1. a=1 and b=2 and c>3:a 和 b 都是等值匹配,锁定唯一分组,组内 c 有序,因此三个字段都能命中索引;
  2. a=1 and b>2 and c in(1,2):b 属于范围查询,b 本身有序可以命中索引,但范围会匹配多组数据,使得后面的 c 失去全局有序性,索引中断,c 无法使用索引检索。

简单说:范围字段本身可用索引,范围之后,索引全部失效

相关推荐
阿演31 分钟前
DataDjinn v0.2.11:SQL 编辑、AI 协作和表格操作继续打磨
数据库·人工智能·sql
l1t2 小时前
duckdb 1.6dev新增的.manual命令
开发语言·数据库
辉灰笔记2 小时前
第一篇:MySQL8.0生产备份实战|XtraBackup全自动全量+增量备份(钉钉告警+异地Binlog归档)
数据库·mysql·钉钉·运维开发
山峰哥2 小时前
‌Explain实战:打开数据库执行计划的黑盒‌
大数据·服务器·数据库·sql·深度优先·宽度优先
wzy06233 小时前
VIP + Orchestrator + 自定义脚本 MySQL 高可用方案
mysql·orchestrator
ClickHouseDB3 小时前
ClickHouse 26.6 版本发布说明
数据库
Wang's Blog3 小时前
Java框架快速入门:深入MyBatis-Plus高级DML操作(ID策略·逻辑删除·乐观锁)
java·数据库·mybatis
小二·14 小时前
RAG + 向量数据库实战:ChromaDB / Milvus / FAISS 选型与性能横评
数据库·milvus·faiss
矜持的左手14 小时前
电子小白的枕边书:电子学(The Art of Electronics)
数据库·restful