暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

索引为什么快?彻底讲透 B+ 树底层原理(通俗 + 深度)

解压泡泡糖 2025-04-30
238

很多人知道索引是数据库性能的关键,但你真的理解它是怎么快起来的吗

大多数人对索引的理解止步于:

“索引就像书的目录,能快速定位数据。”

这比喻不错,但也太抽象。真正的快,是源于 B+ 树的数据结构设计。今天我们深入聊聊这个数据库性能的基石。

什么是 B+ 树?它和二叉树有什么关系?

B+ 树是一种多路搜索树,是数据库索引的核心数据结构(MySQL 的 InnoDB 默认用的就是 B+ 树)。

它和你熟悉的二叉树、红黑树有几个关键区别:

  • 二叉树最多有两个子节点,B+ 树可以有成百上千个子节点(N 叉树)

  • B+ 树所有数据都存在叶子节点,内部节点只负责导航

  • 叶子节点之间通过指针连接成链表,方便范围查询

这意味着什么?

B+ 树天生适合磁盘存储 —— 节点数少,层级少,一次 IO 能读很多数据,查得更快。


为什么数据库偏爱 B+ 树?

原因只有一个字:

但为什么快?这里有 3 个关键点:

1. 节点容量大,IO 次数少

假设一个 B+ 树节点大小为 16KB,每个键值 8 字节,每个指针 8 字节,那一个节点就能容纳上千个键。

B+ 树高度一般只有 2~4 层,意味着:

查一条数据只需要 2~4 次磁盘 IO,性能非常稳定。

相比之下,红黑树、高度深,查找路径长,不适合落地磁盘结构。


2. 所有值都在叶子节点,支持范围查询

B+ 树把数据都放在最底层的叶子节点,这样范围查询就可以通过叶子节点的链式结构一口气往后扫,非常高效。

比如:

select * from user where age between 20 and 30;

只需定位到第一个 age ≥ 20 的节点,然后顺着链表扫到 age > 30 为止。

顺序 + 范围检索,非常快。


3. 内部节点只存键,不存值,提高分支因子

B+ 树的内部节点只存索引键,不存整行数据,这让它在相同内存页大小下,能容纳更多的键(分支因子高),树的高度就更低。

树矮 = 查找路径短 = IO 次数少 = 查询快。


InnoDB 的聚簇索引和二级索引,怎么用 B+ 树?

在 InnoDB 中,索引分为两种:

聚簇索引(Primary Key)

  • 主键索引的叶子节点存放的是整行数据

  • 每张表只能有一个聚簇索引

执行:

select * from orders where id = 123;

如果 id 是主键,就可以通过 B+ 树直接定位到叶子节点,拿到整行数据,无需回表。


二级索引(Secondary Index)

  • 普通索引(非主键)的叶子节点只存索引键 + 主键值

  • 查整行数据时,还需要回表到主键索引查数据

比如:

select * from orders where user_id = 456;

如果 user_id 是普通索引,先在 user_id 的 B+ 树里查到主键,再回到主键树查整行数据。

这个“回表”过程,是导致一些 SQL 慢的根本原因。


覆盖索引为什么快?也能靠 B+ 树实现吗?

所谓覆盖索引,就是:

查询字段 全部包含在索引中,不需要回表。

举个例子:

select user_id, status from orders where user_id = 456;

如果你建立了联合索引:

create index idx_user_status on orders(user_id, status);

这条 SQL 就可以直接从二级索引 B+ 树中读取所有需要的字段,完全不需要回主键树查整行数据,速度提升巨大。

这就是 B+ 树在实战中的威力。


总结:B+ 树快的本质

  • 它是多叉树,层级少,IO 次数少

  • 所有值都在叶子节点,顺序遍历快

  • 节点间有链表指针,支持范围查询

  • InnoDB 通过聚簇索引和二级索引机制,结合 B+ 树实现了高效的数据查找

想写出高性能 SQL,理解 B+ 树是底层基础。

真正的数据库高手,不只是“用”索引,而是知道索引为什么快、什么时候失效、如何设计得更好

文章转载自解压泡泡糖,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论