MySQL 索引

官官方信息技术老师·9 页·深入(追求细节与边界)·0 次浏览·33 天前
信息技术大学

MySQL 索引

计算机基础面试八股 · 第 3 章 数据库(MySQL 与 Redis)

按 空格/→ 演示下一步

问一句
1 / 9 页

全部页面点击任意一页,跳回舞台从这页播放

信息技术大学

MySQL 索引

计算机基础面试八股 · 第 3 章 数据库(MySQL 与 Redis)

1第 1 页 · MySQL 索引

B+ 树与 B 树/哈希索引对

MySQL 选 B+ 树不是偶然:矮胖树层高稳定,叶子成链扫表快,范围查询是主场。

B+ 树
数据全在叶子层,叶子串成有序双向链表
对比 B 树
B 树数据散在各级,范围查询要反复回旋
对比哈希
哈希等值快但不支持范围、排序与前缀
层高
千万行层高也就 3~4 层,三次 IO 定位一行
2第 2 页 · B+ 树与 B 树/哈希索引对

聚簇索引与二级索引

InnoDB 表就是索引组织表:主键索引即数据本体,二级索引存的是主键值。

聚簇索引
叶子存整行数据,就是主键索引本身
二级索引
叶子存索引列+主键值,查完往往要回表
主键选择
自增主键顺序追加不裂页,随机 UUID 是灾难
3第 3 页 · 聚簇索引与二级索引

回表与覆盖索引

二级索引拿到主键还要回聚簇树再查一次:覆盖索引让这一步消失。

回表
二级索引查到主键,再回聚簇索引取整行
覆盖索引
查询列全在索引里,免回表直接返回
EXPLAIN 验证
Extra 出现 Using index 即覆盖生效
4第 4 页 · 回表与覆盖索引

回表判定自测

点击作答

联合索引 (name, age),执行 SELECT name FROM users WHERE name LIKE '张%',会回表吗?

5第 5 页 · 回表判定自测

联合索引与最左前缀原则

联合索引像按声明顺序排的字典:必须从最左列开始连续命中,跳列就断档。

最左前缀
(a,b,c) 支持 a、a,b、a,b,c,跳过 a 直接失效
范围断链
中间列用范围查询后,右侧列无法继续走索引
顺序设计
等值列在前、范围列在后,区分度高的靠前
6第 6 页 · 联合索引与最左前缀原则

索引失效常见场景

索引建了不走,多半是写法作妖:函数包裹、隐式转换、前置通配都是重灾区。

列上计算
函数或运算包裹索引列,优化器弃用
隐式转换
字符串列传数字,类型不匹配索引失效
前置通配
LIKE '%xx' 走不了索引,'xx%' 可以
OR 混写
OR 两侧有无索引混杂,可能整体全表扫
7第 7 页 · 索引失效常见场景

本节要点

  • ✓B+ 树叶子成链,范围查询主场
  • ✓聚簇索引即数据,二级存主键
  • ✓覆盖索引免回表,EXPLAIN 可验证
  • ✓最左前缀 + 范围断链,写法防失效
延伸主题:EXPLAIN 自己的慢查询检查主键是不是自增
8第 8 页 · 本节要点

课后思考

先自己回答,再展开参考答案——能讲出来才算真懂。

1为什么建议用自增主键,随机 UUID 有什么问题?

参考答案自增保证插入总在 B+ 树最右侧顺序追加,页写满才开新页;UUID 随机落点,引发频繁页分裂与数据搬移,写放大、碎片化,还拖累缓冲池命中率。

2索引 (a,b,c) 下,条件 a=1 AND c=3 为什么用不上 c?

参考答案索引按 a、b、c 逐级排序,跳过 b 后 c 在整体里是散乱的,无法定位区间。把 b 的等值补上,或调整索引列顺序,c 才能参与过滤。

3哈希索引那么快,为什么 InnoDB 不默认用它?

参考答案哈希只能等值匹配,范围、排序、前缀匹配全都无能为力,而这些正是业务查询主流;B+ 树等值多走两三层但能力全面、层高又低,综合最优。

9第 9 页 · 课后思考