MySQL 索引:从底层类型到面试避坑

最近在复习数据库这块,发现 MySQL 索引真是面试里的"常青树"。面试官总喜欢通过索引来考察你对底层原理的理解以及实际排查慢查询的能力。

今天我们从类型、特性、实战考题三个维度把索引盘清楚。

一、 MySQL 索引有哪些类型?

咱们可以从三个维度来拆解:

1. 逻辑维度(按功能分)

  • 主键索引 (Primary Key):唯一的,不准有空值。一张表只能有一个。

  • 唯一索引 (Unique Key):值必须唯一,但允许为空。

  • 普通索引 (Normal Index):最基础的索引,没啥限制。

  • 联合索引 (Composite Index) :把多个字段组合在一起建一个索引。这是面试最爱考的点

  • 全文索引 (Full-text):用来搜大文本里的关键词。

2. 物理存储维度(面试重点)

在 InnoDB 引擎下,主要分为:

  • 聚簇索引 (Clustered Index)

    • 叶子节点直接存的是整行数据

    • 一张表只有一个(通常是主键)。

  • 非聚簇索引 / 二级索引 (Secondary Index)

    • 叶子节点存的是主键的值

    • 如果你查的字段不在这个索引树上,就会发生**"回表"**(先查到主键,再去聚簇索引找整行数据)。

3. 数据结构维度

  • B+ 树索引:MySQL 的默认选择。

    • 为什么选它? 因为 B+ 树只有叶子节点存数据,结构稳定,扇出大,磁盘 I/O 次数极少。
  • Hash 索引:虽然等值查询快,但不支持范围查询,所以用得少。


二、 必须掌握的索引特性

1. 最左匹配原则

这是联合索引的灵魂。如果你建了 (a, b, c) 的索引,查询条件必须从 a 开始,不能跳过。

  • a=x and b=y走索引

  • b=y and c=z不走索引 ,因为缺了老大 a

2. 索引下推 (ICP)

一句话解释:把原本由 Server 层处理的过滤操作,下沉到存储引擎层执行。

  • 核心目的 :减少回表次数,降低 I/O 开销。看到 EXPLAIN 里的 Using index condition 就是它了。

3. 覆盖索引 (Covering Index)

如果你查询的字段(比如 select name)刚好就在你用的索引树上,MySQL 就不需要再去聚簇索引查了。这种不需要回表的操作,效率极高。


三、 常见面试题深度解析

咱们拿几个具体的联合索引 (a, b, c) 的例子来分析:

考题 1:条件 a = 2 and c = 1 会走索引吗?

  • 思路 :看最左。a 是前缀,匹配成功;但 b 缺失,导致 c 无法利用 B+ 树的有序性进行二分查找。

  • 答案能用到索引,但只用了一半a 用于在索引树上快速定位;而 c 虽然不能定位,但由于它就在索引树上,可以触发 ICP(索引下推) 在引擎层过滤,减少回表。

考题 2:条件 a > 2 and b = 1 会走索引吗?

  • 核心逻辑"范围之后全失效"

  • 答案a 走索引,b 不走。

    • 因为 a 是范围查询(>),在 a > 2 的范围内,b 的值在全局看是无序的,无法继续利用索引树定位。

    • 此时 key_len 只包含 a 的长度。

追问 :如果是 WHERE b > 10 AND a = 1 呢?

技巧 :MySQL 的查询优化器 会自动调整顺序为 a = 1 AND b > 10。因为 a 是等值,在 a 确定的情况下,b 是绝对有序的,所以 ab 都能命中索引!

考题 3:怎么判断索引到底走没走?

EXPLAIN

  1. type :看到 rangeref 说明走索引了;看到 ALL 请立刻优化代码。

  2. key_len:通过字节数换算,能精准判断出联合索引具体走到了哪一列。

  3. Extra :看到**Using index condition** 说明触发了 ICP;看到**Using index**说明是覆盖索引。


四、 总结:如何写出高质量的索引?

  1. 字段选择:给高频查询、排序、分组的字段加索引。

  2. 区分度:性别这种只有男/女的字段加索引没啥意义(区分度太低)。

  3. 避免失效:不在索引列上做计算、函数操作、或类型转换(比如字符串不加单引号)。

  4. 控制数量:索引不是越多越好,毕竟增删改的时候都要维护索引树。

相关推荐
LSL666_2 小时前
8 Redis 高可用进阶(主从容灾→选举机制→哨兵机制)
数据库·redis·缓存
ShineWinsu2 小时前
对于C++中unordered_set的详细介绍
数据结构·c++·算法·面试·stl·哈希表·unordered_set
iPadiPhone2 小时前
性能优化的“双刃剑”:MySQL 查询缓存深度架构解析与面试复盘
java·后端·mysql·缓存·面试·性能优化
天涯学馆2 小时前
从 V8 引擎看 JS 代码是如何一步步变成机器指令的
前端·javascript·面试
ILL11IIL2 小时前
Mysql 集群技术
数据库·mysql·mha
匀泪2 小时前
云原生(Mysql-MHA高可用集群)
mysql·云原生
茉莉玫瑰花茶2 小时前
C++ ORM 实战:ODB 框架全解析(Linux + MySQL)
jvm·数据库·oracle
chushiyunen2 小时前
django日志使用笔记
数据库·笔记·django
听雪楼主.2 小时前
某客户核心业务系统报ORA-600错误分析处理
数据库·oracle