这里需要知道什么是B+树

从数据结构角度简单分析:

二叉树和B树可以简单理解为通过二分法减少查询的次数,但是仍存在严重的性能问题

1,插入顺序不对时,会退化为链表,时间复杂度由O(logn)变成O(n)。

2.  大数据情况下,查询性能低

为了解决以上问题,选择B树

如何解决

 

自动平衡机制

B-tree与B+树在插入和删除时会执行自动平衡算法。删除导致节点键值对数不足时,会触发合并或重新分配操作(页合并和借键)。

度数为n的b树,每个节点(每个页)最大容纳n-1的键值对,在子节点达到n-1对时,中间的键值对会复制一份到父节点,该子节点分裂为两个子节点。

阶数为5

          [25]               ← 父节点(提升的键)
         /     \
[10, 20]         [25,30, 40]     ← 两个叶子

这些算法保证整棵树的平衡性,防止出现性能退化情况。平衡操作的时间复杂度同样维持在O(log n)级别。

仍存在以下问题:

范围查询性能低

大数据情况,树的高度过高,查询次数过多

为了解决以上问题,MySQL InnoDB选择B+树

如何解决

叶子节点双向链表连接

所有叶子节点通过双向链表连接,形成有序序列。这种结构保证范围查询的高效性,无论插入顺序如何,只需遍历链表即可获取有序数据。链表连接方式使得B+树在保持平衡的同时,支持高效的范围操作。

非叶节点仅做key的区分

B+树的非叶子节点不存储实际数据,因此单个节点(单个页)可以容纳更多键。该特性显著降低树的高度,例如在千万级数据量下,B+树可能仅需3-4层。这种特性确保大数据量下的查询性能稳定。

 

 

 

一、索引

索引结构

 索引的核心定义

  • 索引是MySQL在存储引擎层为字段构建的B+树数据结构,用于快速定位符合条件的数据行,减少磁盘IO。

2. 基础索引类型

索引类型

核心特点

适用场景

主键索引

唯一、非空,一张表仅1个,聚簇索引

主键查询(WHERE id=1

唯一索引

字段值唯一(允许NULL),一张表可多个

唯一字段查询(如手机号phone

普通索引

无唯一性约束,最常用

普通查询字段(如agename

联合索引

多个字段组合的索引

多字段查询(如age+name

覆盖索引

索引包含查询所需所有字段

避免回表(如SELECT id,age FROM user WHERE age=20(age,id)索引覆盖)

3. 什么是回表

聚簇索引是实际存储表数据的结构

每个主键下存储该row的数据

非聚簇索引以字段为key,主键为value

在查询时,先查询出主键再到聚簇索引中查询出该主键下的row数据,这个过程叫做回表

回表

select  * from tb_user where age=20;

不回表

select  id,age  from tb_user where age=20;

4. 索引底层:为什么用B+树?(基础理解)

  • B+树是“平衡多路查找树”,所有数据存在叶子节点,且叶子节点按顺序链表连接;
  • 对比其他结构优势:
  • 比二叉树:层级少(百万数据仅3-4层),查询更快;
  • 比哈希索引:支持范围查询(如age>20),哈希仅支持等值查询。

5. 索引失效核心场景

  • 索引列做运算/函数:age+1=20YEAR(create_time)=2024
select  id,age  from tb_user where age+1=20;
  • 存在隐式类型转换:WHERE phone=13800138000(phone是var类型);
select id,phone from tb_user where phone=12334567;
  • 联合索引不满足“最左前缀”:(age,name)索引,仅查name='张三'
select  id,name  from tb_user where name="张三";
  • LIKE后置模糊匹配:name LIKE '%张'(前缀匹配 张% 生效);
select  id,name  from tb_user where name like "%张";
  • OR条件含非索引列:age=20 OR address='北京'(address无索引)。
select  id,age,address  from tb_user where age=20 OR address='北京';

6. 索引设计基础原则

首先:通过该命令查看当前数据库各语句的访问频次

SHOW GLOBAL STATUS LIKE 'Com_______';

一般只为select语句进行优化(select语句要占比高),select/select+insert+update+delete

  • 只为“高频查询字段”建索引(WHERE/ORDER BY/GROUP BY字段);

  • 联合索引:高频字段放左、区分度高的字段放左(如phone> age);
  • 避免冗余索引(如已有(age,name),无需再建age索引)。

 

索引下推(ICP)基础

语句:

select * from tb_user where age>20 and  reward=200;

范围查询让联合索引(age,reward)中的reward部分失效,从“B+ 树二分查找退化成叶子双向链表顺序扫描 + ICP 过滤 非叶子节点的快速定位能力只用到 age 定位起点,后面的 reward 完全靠过滤,不再参与树遍历。

 

核心定义

索引下推全称 Index Condition PushdownICP,是索引优化机制:在使用联合索引查询时,将原本由 MySQL 服务器层执行的「索引字段过滤逻辑」,下推到存储引擎层完成,减少回表次数和数据传输量,提升查询效率。

核心作用

  • 减少回表 IO:存储引擎层先过滤不符合条件的索引记录,仅将符合条件的记录主键返回给服务器层,再回表查询完整数据;
  • 降低服务器层开销:避免服务器层处理大量无效的索引记录,减少 CPU 计算成本;
  • 对联合索引的长尾条件过滤效果显著。

总结

  1. 适用场景:仅针对非主键的联合索引,且过滤条件是索引中包含的字段(如上面的 reward 是联合索引的一部分);
  2. 识别方式:EXPLAIN Extra 字段显示 Using index condition,表示触发了索引下推;

  1. 与覆盖索引的区别:覆盖索引是「完全不回表」(索引包含所有查询字段),索引下推是「减少回表行数」(仍需回表,只是回表数据更少)

 

有任何相关问题,欢迎评论区讨论

 

 

 

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐