【第5天】每天一个MySQL知识点,百日打怪升级

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
云数据库 PolarDB MySQL 版,列存表分析加速 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: 本文是MySQL索引核心篇,由10年经验DBA精讲B+树原理。深入剖析为何选B+树而非B树/二叉树/哈希表,详解其非叶节点仅存key、叶子双向链表、聚簇与二级索引结构,并结合回表、覆盖索引、页分裂等实战场景,直击面试高频考点。(239字)

索引基础:B+树详解


大家好,我是一名拥有10年以上经验的DBA老兵。

做这个系列,源于一个朴素的愿望:把踩过的坑、总结的经验系统化输出,希望能帮到刚入行或想进阶的兄弟们。

让我们开始今天的第5天内容。


背景引入

💡 说白了:索引就是一本书的目录。没有目录,你想找"事务"这个词,只能一页一页翻;有了目录,直接翻到对应页码。

很多同学知道索引能加速查询,但面试官一问"B+树为什么比B树适合做索引?""为什么不用二叉树?"——就懵了。

今天的目标:搞懂B+树结构,面试必问!


核心概念

一、没有索引会怎样?

没有索引时,MySQL只能全表扫描——从第一行开始,逐行对比,直到找到目标。

-- 没有索引时,查找name='张三'要扫描全表
SELECT * FROM user WHERE name = '张三';

-- EXPLAIN 查看执行结果(type=ALL,说明全表扫描)
-- type列值:ALL → 全表扫描,性能最差

假设一张表100万行,找一个值最多要对比100万次。这就是为什么索引这么重要。


二、为什么是B+树?

面试官喜欢问:为什么MySQL索引用B+树,而不是二叉树、哈希表?

我们逐个对比:

数据结构 查找复杂度 适合场景 不适合做索引的原因
二叉搜索树 O(log n) 内存查找 树太高,磁盘IO多
哈希表 O(1) 等值查找 不支持范围查询
B树 O(log n) 早期数据库 非叶子节点存数据,一次IO拿到的key少
B+树 O(log n) MySQL InnoDB ✅ 叶子节点存数据,非叶子节点只存key

💡 说白了:B+树就像一栋楼——电梯口(非叶子节点)只放楼层号,每间房(叶子节点)放真正的数据。电梯口越小,一层能放的楼层号越多,树就越矮,IO就越少。


三、B+树的关键特征

3.1 非叶子节点只存key,不存数据

好处:非叶子节点只存key,一个页(16KB)能存更多key,树更矮,IO更少。

3.2 叶子节点用双向链表连接

这是B+树和B树最大的区别——B+树的叶子之间有指针,B树没有

好处

  • 范围查询极快:找到起点后,顺着链表往后扫就行
  • 排序查询天然有序:ORDER BY不用额外排序

💡 说白了:B+树的叶子像一排人手拉手,找到第一个人,后面的跟着就出来了。B树呢?每找一个人都要重新回上一层找,效率差远了。

面试必问

  • B+树和B树有什么区别?
  • 为什么MySQL用B+树而不是B树做索引?

📝 面试解答

Q: B+树和B树有什么区别?

image.png

image.png

三个核心区别:

  • 非叶子节点:B+树只存key,B树存key+数据 → B+树一个页能存更多key,树更矮
  • 叶子节点:B+树所有数据都在叶子,B树数据分散在各层 → B+树查询稳定,都是O(log n)
  • 叶子链表:B+树叶子之间有双向链表,B树没有 → B+树范围查询极快

Q: 为什么MySQL用B+树而不是B树做索引?

  1. IO更少:B+树非叶子只存key,同样16KB的页能存更多key,树更矮,IO次数更少
  2. 范围查询更快:叶子之间有链表,找到起点后顺着扫就行;B树要中序遍历
  3. 查询更稳定:所有数据都在叶子节点,每次查询路径长度一样

四、InnoDB的索引结构

InnoDB有两种索引:聚簇索引二级索引

4.1 聚簇索引(主键索引)

聚簇索引的叶子节点存的是整行数据

image.png

💡 聚簇索引 = 数据本身。InnoDB的数据就是按主键顺序存的,所以主键查询是最快的

4.2 二级索引(非主键索引)

二级索引的叶子节点存的是主键值,不是整行数据。

image.png

查name='张三',先用二级索引找到主键id=30,再回聚簇索引找整行数据——这个过程叫回表

面试必问

  • 什么是聚簇索引?什么是二级索引?
  • 什么是回表?

📝 面试解答

Q: 什么是聚簇索引?什么是二级索引?

  • 聚簇索引:叶子节点存整行数据,数据按主键顺序存储。一张表只有一个聚簇索引。
  • 二级索引:叶子节点存主键值,查到主键后需要回聚簇索引取完整数据。

Q: 什么是回表?

通过二级索引找到主键值,再回聚簇索引查整行数据的过程叫回表

回表意味着多一次B+树查找,所以二级索引比主键索引慢。

避免回表的方法:覆盖索引(后续章节讲)——让查询只需要走二级索引就能拿到所有需要的列。


实战案例

场景一:查看索引结构

-- 创建测试表及执行结果
CREATE TABLE t_index_demo (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT,
    INDEX idx_name (name)
) ENGINE=InnoDB;

-- 查看索引
SHOW INDEX FROM t_index_demo;
-- 结果:会看到两个索引
-- 1. PRIMARY(聚簇索引,列id)
-- 2. idx_name(二级索引,列name)

-- 用EXPLAIN观察索引使用
EXPLAIN SELECT * FROM t_index_demo WHERE id = 1;
-- type=const,走主键索引,最快

EXPLAIN SELECT * FROM t_index_demo WHERE name = '张三';
-- type=ref,走二级索引,需要回表

场景二:观察回表过程

-- 回表示例及执行结果
-- 只查主键,不需要回表
EXPLAIN SELECT id FROM t_index_demo WHERE name = '张三';
-- Extra: Using index → 覆盖索引,不回表!

-- 查所有列,需要回表
EXPLAIN SELECT * FROM t_index_demo WHERE name = '张三';
-- Extra: NULL 或 Using where 或留空 → 回表查询

💡 说白了:查 id 不回表(二级索引叶子就有),查 * 要回表(二级索引叶子没age等列)。


场景三:B+树的分裂

-- 顺序插入(主键自增,不分裂)
-- InnoDB主键自增时,B+树顺序追加,不会发生页分裂
INSERT INTO t_index_demo (name, age) VALUES ('张三', 25);
INSERT INTO t_index_demo (name, age) VALUES ('李四', 30);
-- ... 顺序插入,性能好

-- 乱序插入(可能触发页分裂)
-- 如果主键不是自增的,插入可能触发B+树的页分裂,导致性能下降

💡 这也是为什么主键推荐自增——顺序插入不会触发页分裂,性能最好。


避坑指南

⚠️ 真实踩过的坑:

  1. 主键乱序导致页分裂

    • 主键不是自增的(如UUID),插入时B+树频繁分裂
    • 建议用自增主键,顺序插入效率最高
  2. 二级索引回表导致慢查询

    • SELECT * 走二级索引必须回表,比主键索引慢
    • 能用覆盖索引就用覆盖索引,避免回表
  3. 索引列数据太大影响B+树高度

    • 索引列越短,一页存越多key,树越矮
    • VARCHAR(255)做索引比INT做索引,树更高更多IO
  4. 混淆聚簇索引和二级索引

    • 聚簇索引只有一张表一个,就是主键
    • 二级索引叶子存的是主键值,不是数据行指针

思考题

🤔 互动时间:

  1. 为什么InnoDB表必须有主键?如果没有定义主键会发生什么?
  2. 覆盖索引为什么不需要回表?

总结

🎯 面试考点

  • B+树 vs B树:非叶子只存key、叶子有链表、查询稳定
  • 聚簇索引:叶子存整行数据,按主键顺序存储
  • 二级索引:叶子存主键值,需要回表
  • 回表:二级索引→主键值→聚簇索引→整行数据
  • 自增主键避免页分裂,性能最优

💡 AI实战建议:让自己的AI助手记住建表规范检查清单,每次写CREATE TABLE时自动检查:

  • 必须有主键,且推荐自增
  • 索引命名遵循规范:普通索引以 idx_ 开头,唯一索引以 uk_ 开头
  • 联合索引列数不超过5列

下期预告:索引优化:何时建索引、何时不建 —— 面试必问!

全本合集《每天一个MySQL知识点,百日打怪升级》 您的关注是我每日更新的动力


有问题欢迎评论区交流,明天见!

相关文章
|
12天前
|
人工智能 运维 架构师
我在 AIP 智能体平台踩过的坑,都在这篇企业 AI 落地经验里了
软件架构师罗小东分享企业AI落地实战经验:聚焦AIP智能体平台建设中的真实坑点与解法——涵盖智能体全生命周期管理、多源知识库语义检索、MCP工具集成及多模型中立架构设计,强调“解决问题”而非堆砌功能。(239字)
|
1月前
|
机器学习/深度学习 搜索推荐 算法
拆解推荐系统:候选生成、过滤、排序、多样性的分层设计
推荐系统是端到端流水线,非单一算法:涵盖候选生成、过滤、特征工程、多目标排序、多样性调控与反馈闭环。强调关注点分离,以保障质量、速度与行为可控。动手前须明确定义Item、用户行为及成功指标。
305 12
拆解推荐系统:候选生成、过滤、排序、多样性的分层设计
|
1月前
|
人工智能 JavaScript API
(技术贴)别被全网爆火的OpenClaw骗了!实测2小时,真不适合普通人
别被全网爆火的OpenClaw误导!实测2小时发现:部署卡顿、API成本高(日耗几十至千元)、报错难排查,需懂命令行与调试——它本质是开发者框架,非普通人开箱即用工具。现阶段,等待成熟或选择成熟产品更明智。
338 6
|
1月前
|
缓存 安全 Python
5个让Python代码更优雅的实用技巧
5个让Python代码更优雅的实用技巧
239 138
|
1月前
|
NoSQL 网络协议 Cloud Native
【Azure Redis】云原生环境下的 Redis 超时之谜:为什么 15 分钟后应用才恢复?
云原生中Redis短暂不可用后应用持续超时15分钟?问题不在Redis,而在Linux TCP默认重传机制(tcp_retries2=15)与长连接模型的错位。需三管齐下:调低内核重传次数、客户端显式配置超时与自动重连、应用层引入断路器与弹性重试。
163 20
|
11天前
|
安全 Linux 数据库
Omnissa Horizon 8 2603 发布 - 虚拟桌面基础架构 (VDI) 和应用软件
之前称为 VMware Horizon, 通过高效、安全的虚拟桌面交付增强您的工作空间
103 3
Omnissa Horizon 8 2603 发布 - 虚拟桌面基础架构 (VDI) 和应用软件
|
12天前
|
缓存 NoSQL Java
[012][缓存模块]基于 Spring Cache 的缓存操作模版,支持Caffeine缓存, Redis缓存及两级缓存
本项目基于Spring Cache抽象,提供Caffeine本地缓存、Redis分布式缓存及两级缓存(Caffeine+Redis)的统一操作模板。通过工厂模式与模板方法,封装get/put/delete/异步加载等能力,支持租户隔离、类型安全与Spring生命周期集成,显著简化缓存接入。(239字)
65 3
[012][缓存模块]基于 Spring Cache 的缓存操作模版,支持Caffeine缓存, Redis缓存及两级缓存
|
1月前
|
弹性计算 人工智能 运维
新购续费同价,阿里云ECS云服务器2核2G3M99元1年、2核4G5M199元1年,2027年3月结束
阿里云打破“新购低价、续费高价”的行业惯例,推出“新购续费同价”的阿里云经济型e实例和通用算力型u1实例长效特惠活动,价格分别为99元/年和199元/年。活动面向新老用户、个人及企业,提供成本确定性。经济型e实例适合轻量级应用,通用算力型u1实例满足企业入门需求。此外,阿里云还为新用户提供轻量应用服务器抢购活动,价格低至38元/年。用户可在活动期内锁定长期低成本云服务。
444 6
|
1月前
|
弹性计算 人工智能 Linux
阿里云ECS/轻量服务器部署 OpenClaw 图文攻略:Slack集成+千问Qwen3.6-Plus与Coding Plan配置教程
本文完整覆盖2026年**阿里云轻量服务器/ECS云服务器部署OpenClaw、本地MacOS/Linux/Windows11全平台搭建、千问Qwen3.6-Plus付费API与免费Coding Plan双模型配置、Slack全球协作工具集成**四大核心流程,搭配全场景高频问题排查方案,所有命令均为实测可直接复制,无需复杂操作即可完成部署。
476 18
|
2月前
|
弹性计算
阿里云服务器ECS的「文件备份」是什么?超出100GB如何收费?
阿里云ECS「文件备份」是免配置、自动化的文件级数据保护服务,支持按需恢复误删文件,30天内可找回。每账号享100GiB免费额度,超量部分按0.037元/GiB/月计费,按日结算。
138 13