大家好,今天不讲零碎知识点,直接把 MySQL 索引 从底层原理、全品类分类、线上实战优化、高频面试题全套吃透。
不管是平时写 SQL 慢查询调优,还是面试被连环追问索引,看完这一篇,基本不用再翻别的资料。全文偏实战、少废话、能直接落地,建议收藏,工作面试随时能用。
一、先搞懂:索引到底是什么?核心价值只有一句话
索引本质:一种帮数据库快速定位行数据的有序数据结构。
没有索引:查询全表逐行扫描,也就是全表扫描,数据量越大越卡。
有索引:先查索引结构,直接定位到磁盘数据位置,大幅减少磁盘 IO,查询性能直接拉满。
通俗类比:书籍目录。想看某一章,不用逐页翻,看目录直接跳页码,索引就是数据库的「查询目录」。
索引核心收益:降 IO、提 QPS、降慢查询
索引小小代价:占磁盘空间、写操作增开销(增删改都要同步维护索引结构)
二、底层原理:为什么 MySQL 只用 B+ 树,不用二叉树、不用哈希?
InnoDB 存储引擎,所有常规索引,底层统一都是 B+ 树。
1)先简单说下 B+ 树核心特点
- 所有数据都在叶子节点,非叶子节点只存索引键+指针,不存完整数据
- 叶子节点天然有序链表相连,范围查询、排序、分组直接顺路扫,效率极高
- 树层高、分支多,节点紧凑,磁盘单次 IO 能读更多有效索引数据
2)为什么不用二叉树/平衡二叉树?
层高太高,数据量大时树会很深,查询要频繁磁盘寻道,IO 爆炸,性能直接崩盘。
3)为什么不用哈希索引?
哈希只适合精准等值查询:= 匹配。
不支持:范围查询、排序、like 前缀匹配、联合索引最左匹配。
线上业务 90% 场景都要范围、排序、分页,所以 InnoDB 默认放弃哈希,全站 B+ 树。
4)一句话吃透索引原理
B+ 树矮胖分层 + 叶子有序链表 + 最小化磁盘 IO = MySQL 索引高性能核心。
三、索引全分类:按引擎、按功能、按结构,一次分清不混淆
面试最容易乱的就是索引分类,我按三个维度整理,看完永远不混。
1)按存储引擎结构划分(底层硬核分类)
① 聚簇索引(主键索引)⭐核心重点
- InnoDB 独有,每张表有且只有一个
- 叶子节点:直接存整行完整数据
- 数据物理存储,完全按主键顺序排列
- 没有主键,InnoDB 自动生成隐藏 rowid 当聚簇索引
特点:主键查询最快,直接拿到全行数据,无需二次查找。
② 二级索引 / 普通索引(非聚簇)
- 叶子节点:只存「索引列值 + 主键值」,不存整行数据
- 查到索引后,需要拿着主键去聚簇索引里回表查完整行数据
- 所有非主键索引,全部都是二级索引
|---------------------------------|
| �� 关键面试点:二级索引查完要回表,回表越多,SQL 越慢。 |
2)按业务功能划分(日常开发最常用)
① 主键索引
非空、唯一、一张表只能一个,自带聚簇属性。
② 唯一索引
索引列全局唯一,允许 NULL,适合手机号、身份证、用户唯一标识场景。
③ 普通索引
最基础索引,无唯一约束,只为提速查询。
④ 联合索引(复合索引)⭐高频重点
多个字段合建一个索引,遵循 最左前缀原则。
例:idx(a,b,c)
能走索引:a、a+b、a+b+c
不走索引:b、c、b+c、a+c
⑤ 覆盖索引(优化神器)
查询需要的所有字段,全部在索引里,不需要回表,性能天花板级别。
⑥ 全文索引
针对大文本模糊检索,替代 like %关键词%,适合文章、内容摘要检索。
3)额外补充:自适应哈希索引
InnoDB 自动维护,不用人工干预,热点页自动缓存哈希映射,提升热点等值查询速度,开发不用管,面试知道即可。
四、索引失效大全:线上最容易踩的坑,直接避坑
很多慢查询,不是没索引,而是索引明明存在,却直接失效。下面全是高频现场坑。
- like 左模糊 / 全模糊:like '%张三' / like '%张三%',索引直接废,只能右模糊 like '张三%'
- 索引列做函数运算、类型转换:where date(create_time) = '2026-01-01'
- 隐式类型转换:字符串字段用数字查、数字字段用字符串查
- or 连接无全索引覆盖:一边有索引、一边无索引,整体不走索引
- 联合索引不满足最左前缀:跳过前置字段直接查后面字段
- not in / not exists / <> 大量数据过滤,容易走全表扫描
- 数据区分度太低:比如性别、状态只有 0/1,建索引基本没用,优化器直接放弃索引
- 优化器成本判断:数据量少、回表代价大,MySQL 认为全表扫描更快,自动放弃索引
五、实战索引优化:可直接落地的生产规范
不讲空话,直接给线上可落地的优化规则,拿来就能用。
1)建索引黄金原则
- 高频 where、order by、group by、join 字段优先建索引
- 区分度高的字段放联合索引左侧
- 优先用覆盖索引,坚决减少回表次数
- 主键用自增 int / bigint,不要用 UUID、无序字符串,避免页分裂、索引碎片
- 少建冗余索引,不要重复建功能重叠索引,浪费写入性能与磁盘
2)SQL 写法立刻优化
- 禁止索引列上写函数、运算、表达式
- 统一字段类型,杜绝隐式转换
- 模糊查询只用右前缀匹配,拒绝前后全模糊
- 大分页不用 limit 100000,10,用主键书签分页优化
- 避免 select *,按需只查需要字段,更容易触发覆盖索引
3)索引运维日常优化
- 定期用慢查询日志 + explain 分析失效索引、冗余索引
- 大表不要高峰期加索引,用 online DDL 低峰期平滑执行
- 长期冷索引直接删除,减负写入链路压力
- 索引碎片高时,定时整理表空间、优化索引结构
六、Explain 快速看索引:三分钟学会排查慢 SQL
优化索引不用猜,直接 explain 看执行计划,核心关键字段认准这几个:
- type:最优级别 system > const > eq_ref > ref > range,尽量避免 all(全表扫描)
- key:实际真正用到的索引,为空就是没走索引
- key_len:索引有效长度,越长越好,判断联合索引命中几个字段
- Extra:出现 Using filesort、Using temporary 必优化;出现 Using index 就是覆盖索引,性能优秀
只要会看这四列,80% 慢索引问题当场定位。
七、面试高频压轴题合集:背完直接通关索引面试
全部是一线大厂高频原题,直接背,面试不翻车。
1)为什么 InnoDB 必须用 B+ 树?
矮胖树层高低、IO 少;叶子有序天然支持范围、排序、分页;非叶子节点轻量化,缓存友好,综合性能碾压其他结构。
2)聚簇索引和二级索引核心区别?
聚簇叶子存全行数据,无回表;二级叶子只存索引+主键,必须回表;一张表仅一个聚簇索引,二级索引可建多个。
3)联合索引最左前缀原理?
索引按字段顺序排序,必须从第一列连续匹配,跳过左侧字段就无法复用索引结构,直接失效。
4)覆盖索引优势是什么?
无需回表、减少随机 IO、查询性能拉满,是日常优化性价比最高的手段。
5)主键为什么不建议用 UUID?
无序主键导致频繁页分裂、索引碎片暴涨、写入性能严重下降,自增主键顺序写入,结构最稳定。
6)索引越多越好吗?为什么?
不是。索引加速查询,但拖累增删改;索引越多,写入链路维护成本越高,磁盘占用越大,越容易出现锁等待、事务卡顿。
八、全文总结:索引一句话口诀
底层全是 B+ 树,聚簇二级要分清;
联合遵循最左序,覆盖索引少回表;
左模糊、函数算,索引直接就失效;
高频查询建索引,冷索引要及时清;
Explain 看 type key,线上面试全都赢。
写在最后
MySQL 索引没有玄学,吃透原理、分清分类、避开失效坑、按规范优化,就能搞定所有业务慢查询和面试考点。