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. 控制数量:索引不是越多越好,毕竟增删改的时候都要维护索引树。

相关推荐
未秃头的程序猿3 小时前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
AI人工智能_电脑小能手4 小时前
【大白话说Java面试题 第125题】【并发篇】第25题:说说 Java 线程的中断机制
java·后端·面试
SamDeepThinking4 小时前
一条UPDATE语句在MySQL 8.0中到底加了几把锁?
后端·mysql·程序员
kyriewen16 小时前
面试官问你:“AI 能写 80% 的代码了,公司为什么还需要你?”
前端·javascript·面试
冬奇Lab16 小时前
每日一个开源项目(第141篇):hiring-agent - HackerRank 开源了他们的简历评分系统,你的简历能得几分?
人工智能·面试·开源
kyriewen20 小时前
今天的科技圈,全在抢英伟达的饭碗
前端·面试·ai编程
Databend21 小时前
在 AWS 中国峰会逛了一天,我在 Databend 展台看到了 Agent 数据基础设施的新思路
数据库·人工智能·agent
张元清1 天前
React useIsomorphicLayoutEffect:修掉 SSR 下的 useLayoutEffect 警告(2026)
前端·javascript·面试
PBitW1 天前
直接让GPT每日训练我!!!😕😕😕
前端·javascript·面试
以和为贵1 天前
前端手写 RAG 踩坑实录:四个让检索"翻车"的坑
前端·人工智能·面试