信息技术大学
MySQL 索引
计算机基础面试八股 · 第 3 章 数据库(MySQL 与 Redis)
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
信息技术大学
MySQL 索引
计算机基础面试八股 · 第 3 章 数据库(MySQL 与 Redis)
B+ 树与 B 树/哈希索引对
MySQL 选 B+ 树不是偶然:矮胖树层高稳定,叶子成链扫表快,范围查询是主场。
B+ 树
数据全在叶子层,叶子串成有序双向链表
对比 B 树
B 树数据散在各级,范围查询要反复回旋
对比哈希
哈希等值快但不支持范围、排序与前缀
层高
千万行层高也就 3~4 层,三次 IO 定位一行
聚簇索引与二级索引
InnoDB 表就是索引组织表:主键索引即数据本体,二级索引存的是主键值。
聚簇索引
叶子存整行数据,就是主键索引本身
二级索引
叶子存索引列+主键值,查完往往要回表
主键选择
自增主键顺序追加不裂页,随机 UUID 是灾难
回表与覆盖索引
二级索引拿到主键还要回聚簇树再查一次:覆盖索引让这一步消失。
回表
二级索引查到主键,再回聚簇索引取整行
覆盖索引
查询列全在索引里,免回表直接返回
EXPLAIN 验证
Extra 出现 Using index 即覆盖生效
回表判定自测
点击作答
联合索引 (name, age),执行 SELECT name FROM users WHERE name LIKE '张%',会回表吗?
联合索引与最左前缀原则
联合索引像按声明顺序排的字典:必须从最左列开始连续命中,跳列就断档。
最左前缀
(a,b,c) 支持 a、a,b、a,b,c,跳过 a 直接失效
范围断链
中间列用范围查询后,右侧列无法继续走索引
顺序设计
等值列在前、范围列在后,区分度高的靠前
索引失效常见场景
索引建了不走,多半是写法作妖:函数包裹、隐式转换、前置通配都是重灾区。
列上计算
函数或运算包裹索引列,优化器弃用
隐式转换
字符串列传数字,类型不匹配索引失效
前置通配
LIKE '%xx' 走不了索引,'xx%' 可以
OR 混写
OR 两侧有无索引混杂,可能整体全表扫
本节要点
- ✓B+ 树叶子成链,范围查询主场
- ✓聚簇索引即数据,二级存主键
- ✓覆盖索引免回表,EXPLAIN 可验证
- ✓最左前缀 + 范围断链,写法防失效
延伸主题:EXPLAIN 自己的慢查询检查主键是不是自增
课后思考
先自己回答,再展开参考答案——能讲出来才算真懂。
1为什么建议用自增主键,随机 UUID 有什么问题?
参考答案自增保证插入总在 B+ 树最右侧顺序追加,页写满才开新页;UUID 随机落点,引发频繁页分裂与数据搬移,写放大、碎片化,还拖累缓冲池命中率。
2索引 (a,b,c) 下,条件 a=1 AND c=3 为什么用不上 c?
参考答案索引按 a、b、c 逐级排序,跳过 b 后 c 在整体里是散乱的,无法定位区间。把 b 的等值补上,或调整索引列顺序,c 才能参与过滤。
3哈希索引那么快,为什么 InnoDB 不默认用它?
参考答案哈希只能等值匹配,范围、排序、前缀匹配全都无能为力,而这些正是业务查询主流;B+ 树等值多走两三层但能力全面、层高又低,综合最优。