MySQL 索引 B+树底层结构详解

MySQL 索引 B+树底层结构详解

一、为什么要用 B+树

全表扫描要逐行读,千万级表一次查询可能几秒。索引的本质是一份排好序的数据目录,让查找从“翻整本”变成“顺着目录跳”。MySQL InnoDB 默认用 B+树做索引结构,它同时适合等值查询和范围查询,磁盘 IO 次数可控。

二、B+树长什么样

B+树是一种多路平衡查找树:

  • 非叶子节点只存键值和指针,不存完整数据,单页能放更多键,树更矮;
  • 所有真实数据(或主键)都存在最底层叶子节点;
  • 叶子节点之间用双向链表串联,天然有序。

一次树高通常只有 3~4 层,千万级数据定位一行只需 3~4 次磁盘 IO,这就是索引快的根本原因。

三、聚簇索引与二级索引

-- 主键索引就是聚簇索引,叶子节点存整行数据
ALTER TABLE user ADD PRIMARY KEY(id);

-- 普通二级索引,叶子节点存主键值,查到后再回表
ALTER TABLE user ADD INDEX idx_name(name);
  • 聚簇索引:叶子节点放完整行数据,一张表只有一个,通常就是主键;
  • 二级索引(辅助索引):叶子节点存主键值,按它查到主键后还要回表取其他列;
  • 覆盖索引:查询列都在索引里,不必回表,性能最好。

四、为什么不用二叉树或哈希

  • 二叉树/红黑树在数据量大时树很高,磁盘跳转次数多;
  • 哈希索引只适合等值匹配,无法做范围查询、排序、最左前缀;
  • B+树矮胖、叶子有序链表,范围扫描和排序都顺。

五、最左前缀原则

联合索引 (a, b, c) 按建立顺序排序,查询必须从最左列开始:

WHERE a = 1 AND b = 2 AND c = 3; -- 完整命中
WHERE a = 1 AND c = 3;          -- 只用上 a,中间断了
WHERE b = 2;                    -- 走不到索引

跳过中间列,后面的列就无法继续利用索引。

六、索引失效的常见情况

  1. 对索引列做函数、运算、类型转换:WHERE YEAR(create_time)=2026;
  2. LIKE '%xx' 前导通配符;
  3. 联合索引没按最左前缀;
  4. OR 连接的列里有不带索引的;
  5. 数据量小或优化器判断全表扫描更划算时主动放弃索引。

七、如何验证命中索引

EXPLAIN SELECT * FROM user WHERE name = '张三';

看 type(ref 优于 ALL)、key(实际用的索引)、Extra(出现 Using index 说明覆盖索引)。

八、总结

B+树靠“非叶存键、叶存数据、叶子链表”把查找压到几次 IO;聚簇索引存整行、二级索引存主键、覆盖索引免回表;建索引要遵守最左前缀,避免列上运算和前导模糊。理解底层结构,才能正确设计联合索引、判断 EXPLAIN 结果,而不是盲目加索引。


emer 发布于  2026-11-15 07:16 
'); })();