十年大厂员工终明白:MySQL性能优化的尽头,是对B+树的极致理解

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

存储引擎 存储引擎是数据库管理系统(DBMS)或键值存储系统的核心组件,它定义了数据在持久化存储介质上如何组织、存储、检索和管理。不同的存储引擎针对特定负载(如读密集型、写密集型、混合型)和数据模型(如关系型、键值型、文档型)进行优化。 目前常见的存储引擎使用的存储数据结构有如下几种。 1)哈希表(Hash Table):提供O(1)平均时间复杂度的单点查询(精确键匹配)。非常适合键值(Key-Value)存储,但天然不支持范围查询或有序遍历(除非对整个数据集扫描)。 2)B+树(Balance+ Tree):为磁盘I/O优化的多路平衡搜索树。广泛用于关系型数据库(如MySQL InnoDB, PostgreSQL)的索引和数据存储。支持高效的单点查询、范围查询和有序遍历。对读密集型和混合型负载友好。 3)LSM树(Log-Structured Merge Tree):专为高写入吞吐量设计的结构。通过将随机写转换为内存中的有序写入和磁盘上的顺序批量写入来优化写性能。广泛应用于写密集型的NoSQL数据库(如Google Bigtable, Apache HBase, Cassandra, RocksDB, LevelDB)。

MySQL B+树

MySQL的存储引擎,主要分InnoDB和MyISAM。InnoDB是MySQL的默认引擎,InnoDB使用B+树存储数据。表中的数据(主键索引)和辅助索引最终都会使用 B+ 树来存储,其中前者会以 <id, row> 的方式存储,而后者会以 <index, id> 的方式进行存储。

为了分析 InnoDB 选择 B+ 树作为其索引结构的原因,可以将其与 B 树和哈希表进行对比。随着互联网的快速发展,数据存储规模已攀升至千万甚至亿级,而典型的互联网应用场景往往是读多写少。例如,热点新闻的访问、商品列表的展示以及基于价格、地理位置等条件的智能化推荐排序,都需要高效的数据查询和排序能力。因此,数据存储结构需要满足以下核心需求。 1)高效的查询性能:尤其是在范围查询和排序操作上,需要具备优异的性能表现。 2)充分利用顺序 I/O 和 Page Cache 机制:通过优化 I/O 性能,减少磁盘访问的延迟。 3)支持大规模数据存储:在保证高效查询的同时,尽可能减少写入操作的 I/O 开销。

由于哈希映射关系,哈希表在查找单条数据时候,能保证O(1)的时间复杂读。但哈希表在范围查询和排序遍历时候,只能进行全表扫描并依次判断是否满足条件。全表扫描对数据库的性能影响非常大。比如如下的SQL语句:

SELECT * FROM commodity WHERE price > 10 AND price < 100
SELECT * FROM commodity WHERE ORDER BY price DESC

平均时间复杂度比O(1)稍慢的是O(logn),这类数据结构有平衡二叉树(AVL Tree),红黑树(RB Tree)、B树(B Tree)、B+树(B+ Tree)等。他们天然就支持排序、范围查找操作。

平衡二叉树在一般情况下查询性能非常好,但平衡二叉树单个节点只能保存一个数据,因此当覆盖大量数据时候,平衡二叉树的树高度很高。这意味着当需要通过遍历获取存储在硬盘上的数据时候,需要更多次的I/O操作。硬盘读取时间远远超过数据在内存中比较的时间,这将导致程序大部分时间会阻塞在硬盘 I/O 上。

B树 跟平衡二叉树的不同是,B树是一种多叉树。阶数m决定了B树的节点大小和树的高度。较大的阶数可以容纳更多的键值对,减少树的高度和硬盘访问次数。 B树中每个节点都存放着索引和数据,从下图可见,查询索引为 50 的节点就在第一层,B树只需一次硬盘 I/O 即可完成查找。因此B树的查询最好时间复杂度是 O(1)。

B+树 B+树是B树的一种变种,它与B树的区别是: 叶子节点保存了完整的索引和数据,而非叶子节点只保存索引值。所以查询索引为 50的数据,必须要遍历到叶子节点才能取到,因此查询时间固定为 O(logn)。 常见的B+树阶数可以是100或更大,以适应硬盘上的大量数据。

数据查询 B树的范围查询,比如上图要查询“大于10小于30的数据”,需要进行4次硬盘的随机 I/O 。范围查询的随机 I/O次数不稳定和放大,也是 B 树最大的性能问题: 1)遍历根节点的第一个元素是25,大于 10。 2)遍历左子节点的元素,找到第一个大于10的数据是11。 3)重新遍历根节点,发现不包含小于30的数据。 4)遍历载右子节点的元素,找到最后一个小于30的数据是27。 而B+树叶子节点保存指向下一个叶子节点的指针,叶子节点之间类似于单链表连接起来,因此叶子节点的数据在硬盘里是顺序存储的。当读到某个叶子节点数据时候,硬盘根据局部性原理会提前将相关的数据都读进内存,这使得范围查询和排序很高效。 操作系统在读文件时,根据Page Cache机制将数据加载到页缓存中,页的默认大小是4KB。由于B+树非叶子节点都只是索引值,这就意味B+树一次I/O,相比于B树能读出的索引值更多,从而减少查询时候需要的I/O次数。 不同于操作系统,InnoDB引擎的页大小默认是16KB,如下估算: 1)非叶子节点存放(key,pointer),假设主键ID为bigint类型,长度为8字节,而指针在InnoDB源码中为6字节,一共14字节,即非叶子节点能存放 16KB/14 左右的(key,pointer)。 2)叶子节点中保存的一行记录的数据大小为1KB,大约可以存储16K/1K = 16记录数。 如果B+树高度为2,那么存放总记录数为:根节点指针数单个叶子节点记录行数 = 16KB/14 * 16 大约 1.8w+ 数据。 如果B+树高度为3,那么存放总记录数为:根节点指针数单个叶子节点记录行数 = 16KB/14 * 16KB/14 * 16 大约2kw+数据。

数据写入 相比于数据读取场景,B+树在写密集型场景的性能并不理想。这主要原因是:B+树在写入(插入、删除、更新)时,为维持树的平衡,可能触发节点分裂、合并。这些操作可能涉及多个磁盘页的修改,导致随机I/O,且需要更新Page Cache中的对应页,使其失效。因此,在写密集型场景下,B+树性能不如专为写入优化的结构。

因此B+树也通过一些优化策略来提高写操作的性能。比如使用写缓冲区(Write Buffer)来缓存写操作,然后定期将缓冲区中的数据批量刷入硬盘,将随机I/O合并为后续的顺序I/O。此外可以使用多版本并发控制机制(MVCC)来减少写入时候的锁竞争和提高并发性能。

Mysql索引结构全维度比较 前言 在MySQL中,无论是Innodb还是MyIsam,都使用了B+作索引结构(这里不考虑hash等其他索引)。本文将从最普通的二叉查找开始,逐步说明各种解决的问题以及面临的新问题,从而说明MySQL为什么选择B+作为索引结构。 一、二叉查找(BST):不平衡 二叉查找(BST,Binary Search Tree),也叫二叉排序,在二叉的基础上需要满足:任意节点的左子上所有节... 阅读详情

相关推荐

腾讯IEG后台开发实习生面经:从简历到Offer的全流程复盘

在互联网后台开发领域,高并发和网络编程是衡量系统能力的关键指标,尤其对于游戏后台而言,C++与分布式系统更是技术基石。面试官往往通过基础功底、项目深度、工程能力等多维度筛选候选人,而扎实的操作系统、网络协议知识以及场景设计思维则是通关必备。本文从面试官视角拆解腾讯IEG后台开发实习生的考察逻辑,结合真实流程中的高频八股文与手撕算法,复盘从简历投递到HR面的完整路径,帮助求职者理解大厂选拔标准,掌握针对游戏后台方向的备战策略与应答技巧。

weixin_29015051的博客 395

MySQL的b+

MySQL的b+

学无止境 948

广联达校招笔试复盘:Java基础与算法高频考点全解析

校招笔试是技术岗求职的第一道门槛,考察的是候选人对基础知识的掌握程度和工程实践能力。从Java集合框架的底层原理到数据结构中的链表反转与二叉遍历,再到数据库索引为何选择B+以及TCP三次握手的深层原因,这些看似分散的知识点,实则是衡量开发者基本功的核心标尺。理解ArrayList与LinkedList的适用场景、String拼接的性能差异、volatile与synchronized的语义边界,以及最左前缀原则、事务隔离级别等,能让你在面对真实业务场景时做出更合理的技术选型。本文以广联达校招笔试为切入点,

weixin_32183107的博客 283

MySQL索引-B+(讲得通透)

索引这个词,相信大多数人已经相当熟悉了,很多人都知道MySQL的索引主要以B+为主,但是要问到为什么用B+,恐怕很少有人能把前因后果讲述的很完整。本文就来从头到尾介绍下数据库的索引。 索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据。索引最形象的比喻就是图书的目录了。注意这里的大量,数据量大了索引才显得有意义,如果我想要在[1,2,3,4]中找到4这个数据,直接对全数据检索也很快,没有必要费力气建索引再去查找。索引在mysql数据库中分三类: B+索引、Hash索引、全..

尽量致力于发表微服务、中间件和算法等原创作品。 1万+

MySQL索引底层:B+详解

如果插入关键字后,叶子节点当前含有的关键字数目等于阶数m,则插,该节点开始 「分裂」为两个新的节点,一个节点包含m/2 个关键字,另外一个关键字包含m/2个关键值。最后插入28,发现当前节点关键字也是不小于阶数4了,于是分裂,于是分裂, 第 4/2=2个,也就是36上移到父节点,因父子节点只有2个关键值,还是小于4的,所以不用继续分裂,插入完成。找到包含关键值的结点,如果关键字个数大于m/2-1,并且关键值是当前节点的最大(小)值,并且该关键值存在父子节点中,那么删除该关键字,同时需要相应调整父节点的值。

weixin_44837153的博客 3286

Mysql B+

①介绍一下 B tree, 多路平衡查找(balance tree) 通过名称多路平衡就知道这个的特点,是平衡二叉的基础上改进的多路(支持多个分叉)。 所有的叶子节点在同一高度,非叶子节点也会存放数据。 假设要从上图中查找id = X的数据,B TREE 搜索过程如下: 取出根磁盘块,加载40和60两个关键字。 如果X等于40,则命中;如果X小于40走P1;如果40 < X < 60走P2;如果X = 60,则命中;如果X > 60走P3。 根据以上规则命中后,接

u010648194的博客 8693

jemalloc思想的极致演绎:深度解构Netty内存池的精妙设计与实现

这种频繁的移动会导致额外的性能开销。最,当事件驱动降低了线程调度的微观成本,资源复用消除了内存管理的隐性消耗,而分层解耦提升了模块协作的宏观效率时,一个高吞吐、低延迟的健壮系统便水到渠成。例如:在q025的范围为[25%, 50%) 时,即使Chunk的使用率降低到25%,它仍然可以保留在q025中,直到使用率降低到25%以下(即进入q000的范围)。为了提高内存分配的利用率,Netty在分配小于8KB的内存时,不再直接分配整个Page,而是将Page进一步划分为更小的内存块,由Subpage进行管理。

2501_93908980的博客 754

java连接linux服务器执行命令,稳进大厂

其实互联网职业可以大致分两个阶段,在毕业后的3到5年内主要都是以学习、积累为主,从一开始啥都不懂的校园“新鲜人”向“职业人”转变。如果你是Java开发者,在这个阶段你会学习: 1、基础的Java知识,多线程、集合类、JVM 2、进阶知识,设计模式、系统设计和方法论 3、主流框架,SpringSpring Boot、MyBatis…… 4、微服务,Dubbo、ETCD、Spring Cloud…… 5、数据库,Redis、ES、MySQL、分库分表 分享一下我的学习之路 2017从杭州师范大学(也是马云

m0_57501637的博客 160

2023大厂面经深度解析:八股文背后的原理与场景

技术面试正在从记忆型考察转向原理与场景的双重验证。以高并发系统为例,Kafka之所以能支撑百万级吞吐,本质上依赖顺序写磁盘、页缓存、零拷贝与分区并行等底层机制,这些原理是分布式架构师的核心素养。并发编程中的锁选型(synchronized vs ReentrantLock)也要求候选人能结合真实场景说明取舍。与此同时,Agent面经与AI自动生成case如何保证准确这类新兴议题,已在各岗位面试中高频出现,折射出AI能力已成为技术人才的基本盘。2023年5月大厂面经显示,Java八股、嵌入式八股、测试八股等方

weixin_34007886的博客 358

从立项到上线三个月:面试鸭在线刷题工具的产品与技术复盘

在线刷题是程序员面试准备中的高频场景,力扣等平台虽提供海量题目,但缺乏针对面试的系统化路径。面试刷题工具的核心价值在于将算法练习、八股文背诵和场景题训练整合为一条清晰的学习曲线,并通过记忆曲线与错题回流机制提升复习效率。在工程实践上,需要兼顾题库质量、冷启动推荐和性能优化。以面试鸭为例,复盘其从产品定位、题库体系设计、核心功能实现到冷启动运营的完整过程,并整理上线踩坑经验,为工具型产品开发者和面试准备者提供参考。

weixin_34037515的博客 420

拆解阿里2015研发工程师笔试卷:大厂校招核心考点与复习策略

在软件工程实践中,数据结构与算法是衡量工程师基础素养的核心标尺,而操作系统与网络协议则决定了系统在真实环境中的表现。大厂研发岗位的笔试,本质上是将底层原理与工程权衡结合的压力测试,考察候选人在有限时间内对经典问题的迁移能力。从HashMap的红黑阈值到线程池参数调优,从TCP重传到内存泄漏定位,这些知识点既是笔试高频考点,也是线上排查与架构设计的基本功。以一份真实的阿里巴巴2015研发工程师A笔试卷为样本,逐模块剖析大厂笔试题的命题逻辑、复习优先级与答题策略,帮助读者以“工程视角”重构知识体系,为校招笔试

weixin_28730403的博客 302

2026年AI时代程序员学习路线图:从零基础到拿大厂Offer的完整规划(2万字深度长文)

本文为不同阶段的程序员绘制完整学习路线图,覆盖零基础入门到架构深挖四个阶段,附在职跳槽和应届校招时间规划模板及常见误区避坑指南。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 999

Java面试新趋势:从八股文到场景化深度考察的实战应对策略

在Java技术领域,面试考察正从传统的知识点背诵转向对技术原理深度理解和复杂场景解决能力的评估。理解技术原理是掌握Java并发编程、JVM性能调优、MySQL索引优化等核心概念的基础。这些原理知识能够帮助开发者在高并发、分布式系统等实际应用场景中,设计出高性能、高可用的解决方案,从而体现其技术价值。例如,深入理解JVM内存模型和垃圾回收机制,对于诊断线上OOM问题和进行系统调优至关重要;掌握MySQL的B+索引原理和事务隔离级别,是设计千万级数据表架构和保证数据一致性的前提。当前,面试官更关注候选人能否将

weixin_34210740的博客 346

运维开发笔试复盘:网易经典考点与备考思路

从操作系统到网络协议,基础架构知识是运维开发岗位的立身之本。无论容器化如何演进,Linux进程管理、TCP/IP状态流转、Shell文本处理与MySQL索引原理等底层机制始稳定不变。理解这些核心概念,不仅有助于应对大厂笔试,更能指导日常的故障排查与性能优化。本文以网易校招运维开发笔试试卷为样本,拆解考点分布、解题思路与高频失分点,梳理出一条从基础理论到工程实践的学习路径,帮助求职者构建系统化的知识体系。

weixin_28730037的博客 213

从CS:APP到系统思维:构建程序员底层认知的实践指南

计算机系统是软件与硬件协同工作的复杂整体,其核心原理在于理解数据如何在内存中表示、CPU如何执行指令以及操作系统如何管理资源。从信息表示、内存层次结构到进程与并发控制,这些基础概念构成了高性能、高可靠软件系统的基石。掌握系统底层知识,能帮助开发者编写缓存友好的代码、优化内存布局、诊断性能瓶颈,并深刻理解网络通信与并发同步的内在机制。本文以《深入理解计算机系统》为蓝本,聚焦异质的数据结构在内存中的对齐与布局优化,以及如何通过分析内存访问模式来提升程序性能,为开发者提供从理论到实践的完整学习路径与实验指南。

weixin_30315723的博客 363
上一篇: springboot框架项目实践应用(springcloud alibaba整合sentinel)
下一篇: 一把锁的两种承诺:synchronized如何同时保证互斥与内存可见性?
程序员职业指南
博客等级 码龄4年 2107粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值