最近在复习数据库这块,发现 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是绝对有序的,所以a和b都能命中索引!
考题 3:怎么判断索引到底走没走?
看 EXPLAIN。
-
type :看到
range、ref说明走索引了;看到ALL请立刻优化代码。 -
key_len:通过字节数换算,能精准判断出联合索引具体走到了哪一列。
-
Extra :看到**
Using index condition** 说明触发了 ICP;看到**Using index**说明是覆盖索引。
四、 总结:如何写出高质量的索引?
-
字段选择:给高频查询、排序、分组的字段加索引。
-
区分度:性别这种只有男/女的字段加索引没啥意义(区分度太低)。
-
避免失效:不在索引列上做计算、函数操作、或类型转换(比如字符串不加单引号)。
-
控制数量:索引不是越多越好,毕竟增删改的时候都要维护索引树。
