大数跨境

MySQL 专题 02|索引为什么快?B+树/最左前缀/回表讲透

MySQL 专题 02|索引为什么快?B+树/最左前缀/回表讲透 种子AI编程学习
2026-10-04
0
导读:面试高频,也是慢 SQL 优化的根基。用最少的字讲清三件事。
     面试高频,也是慢 SQL 优化的根基。用最少的字讲清三件事。   

一、为什么是 B+树

索引的本质是"用空间换时间",让查找不用全表扫。能加速查找的结构很多,MySQL 选 B+树,原因就三点:

  • 矮胖
    :一个节点能放很多 key(默认 16K 页),三层就能存千万级数据,查找只要约 3 次磁盘 IO。
  • 叶子成链
    :所有数据都在叶子节点,且用双向链表串起来,范围查询顺着链表走就行,不用回树里绕。
  • 非叶子只存 key
    :把更多 key 塞进节点,树更矮,IO 更少。对比之下,B 树数据分散在各层、Hash 不支持范围、红黑树太高(IO 多)。
一句话:B+树 = 矮(少 IO)+ 叶子链表(好范围)。

二、聚簇索引长什么样

InnoDB 里,表数据本身就是按主键组织的 B+树,叫聚簇索引:非叶子节点存「主键值 + 指针」,叶子节点存整行数据。

没建主键时,InnoDB 会挑唯一列;再没有就隐式生成 row_id。所以主键索引叶子直接是数据,这也是"主键查询最快"的原因。

二级索引(普通/联合索引)是另一棵 B+树:叶子节点存「索引列值 + 主键值」,不是整行。记住这点,才能理解下面的"回表"。

三、最左前缀原则

联合索引 (a, b, c) 在 B+树里按 a→b→c 顺序排序,像电话簿:先按姓、同姓按名。

能命中:

  • WHERE a=1
  • WHERE a=1 AND b=2
  • WHERE a=1 AND b=2 AND c=3

跳最左就废:

  • WHERE b=2❌
     没 a,只能全扫
  • WHERE a=1 AND c=3⚠️
     只用上 a,c 失效(跳过 b)
口诀:最左前缀 = 从左边连续匹配,断了后面失效。 补充:范围查询(>、<、LIKE 'abc%')能命中,但它后面的列用不上索引,如 a=1 AND b>2 AND c=3 里 c 失效。

四、回表与覆盖索引

二级索引叶子只存主键,当查询需要索引列以外的字段时,InnoDB 要拿主键回聚簇索引再查一次整行——这就是回表。

-- 有联合索引 (name, age) SELECT * FROM user WHERE name='张三';  -- 找到主键后回表取全部字段

只查索引里就有的列,不用回表:

SELECT name, age FROM user WHERE name='张三';  -- name、age 都在索引里 → 覆盖索引,直接返回

"索引已包含查询所需全部字段"叫覆盖索引,省一次回表更快。所以尽量少写 SELECT *,要哪些列查哪些,更容易命中覆盖索引。

五、面试速记

  1. 为什么 B+树?
     矮(少 IO)+ 叶子链表(好范围);Hash 不支持范围,红黑树太高。
  2. 聚簇索引
    叶子存整行,二级索引叶子存「索引值 + 主键」。
  3. 最左前缀
    :从左边连续匹配,断了失效;范围查询后列失效。
  4. 回表
    :二级索引查非索引列需回主键索引再查一次。
  5. 覆盖索引
    :查询列都在索引里,不回表更快;少写 SELECT *。
  6. 主键用自增整型最好
    :顺序追加,页分裂少,索引更紧凑。

六、一句话带走

B+树靠"矮 + 叶子链表"把查询打到 3 次 IO 内;联合索引守最左前缀;二级索引查整行会回表,用覆盖索引避开。讲清这三句,索引面试就过了。

MySQL索引面试

下一篇预告:Buffer Pool 是怎么把查询再快一个量级的。


【声明】内容源于网络
0
0
种子AI编程学习
1234
内容 59
粉丝 0
种子AI编程学习 1234
总阅读32
粉丝0
内容59