一文讲透mysql的索引树:从图书馆的故事开始

RK3568点不亮EK79007 MIPI屏?别急着改时序,先检查这个初始化命令 本文深入解析RK3568开发板调试EK79007 MIPI屏幕时初始化命令的关键作用,揭示80%的时序问题实际源于命令配置不当。通过典型故障案例,详细拆解初始化命令的调试方法、寄存器映射及系统化排查流程,帮助工程师快速定位和解决屏幕点亮问题。 阅读详情

 

一、为什么需要索引?先讲个图书馆的故事

想象一个巨大的图书馆,里面有上千万本书,但所有书都是乱序堆在地上的。你要找一本编号为“9527”的书,唯一的办法就是从第一本开始,一本一本地翻看编号,直到找到为止。这可能需要几天时间。这就是数据库没有索引时的“全表扫描”,效率极低。

聪明的图书管理员想了个办法:建立一本“索引目录册”。

  1. 第一版目录(简陋版):目录册上按顺序记录了每本书的编号和它的具体位置(如:A区-3排-2架-5层)。找书时,你先在目录册里快速翻到编号“9527”,然后直接去对应位置拿书。快多了!这就像在一个有序数组里用二分查找,但目录册本身太厚,翻起来也慢。

  2. 第二版目录(升级版)——这就是B+树:管理员把目录册升级成了一个多级的、树状的结构。

    • 顶层(根目录):只有一页纸,上面写着:“编号1-5000的书,去1号子目录查;编号5001-10000的书,去2号子目录查...”
    • 中层(子目录):你根据根目录指引,找到2号子目录。它上面写得更细:“编号5001-6000,去A书架;编号6001-7000,去B书架...”
    • 底层(书架本身):你最终来到B书架,这里的书严格按照编号顺序排列,并且书架之间用绳子连起来,方便按顺序浏览。你很快找到了编号“9527”的书。

这个“根目录-子目录-书架”的多级结构,就是B+树索引。 它让查找次数从千万级,降低到了仅仅3次(根→子→书架)。


二、索引树是怎么“长”出来的?用自增ID建表为例

现在,我们扮演数据库,亲自建一个“图书馆”。假设我们的“书架”(在MySQL里叫页)很小,一个书架只能放4本书(实际能放很多)。

我们建一个用户表,主键ID是自增的(就像给每本新书一个按顺序递增的编号):

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT, -- 自增编号
    name VARCHAR(100)
);

第1步:第一本书上架(id=1)
图书馆刚开业,我们申请了第一个书架(页10)。把书《id=1, name=张三》放进去。此时,这个书架既是“总目录”,也是“藏书架”。树只有1层高。

[书架10:总目录 & 藏书架]
| id=1 (张三) | (空) | (空) | (空) |

第2步:顺序上架新书(id=2, 3, 4)
新书源源不断,编号顺序增加。我们都把它们按顺序放到同一个书架10的后面空位。

[书架10:总目录 & 藏书架]
| id=1 (张三) | id=2 (李四) | id=3 (王五) | id=4 (赵六) | <- 书架满了!

第3步:关键!插入id=5,书架满了怎么办?——分裂与重组
这是最容易误解的地方。当要放入《id=5, name=小明》时,书架10满了。

  • 如果新书编号是随机的(比如id=500),它可能应该插在书架中间。这时,管理员不得不把书架10的书搬出一半,放到一个新书架20里,然后更新总目录,这个过程空间利用率会接近50%。
  • 但我们是自增ID! 新书id=5永远是当前最大编号。聪明的管理员(InnoDB存储引擎)会做一个优化:他几乎不动书架10的书,而是直接申请一个新书架20,把id=5这本新书放进去。然后,他新建一个真正的总目录页(页30),用来记录:“书架10里的书,编号都小于5;书架20里的书,编号从5开始”。
           [总目录页30]
        “找<5的去10,找>=5的去20”
           /            \
          /              \
[书架10-藏书架]      [书架20-藏书架]
|1|2|3|4|           |5|(空)|(空)|(空)|
(几乎满的)        (新的,准备放6,7,8...)

看,自增ID插入,几乎不会浪费50%空间,老书架(页10)依然是满的。空间浪费严重的“对半分裂”,更多发生在随机插入的时候。

第4步:树继续长高
随着id=6,7,8...的书进来,它们会顺序填满书架20。当书架20也满时,再次用优化方式分裂出书架40。当“总目录页30”的格子也写满时,总目录自己也会分裂,产生更高一级的“超级总目录”,树就从2层长高到3层。最终,所有“书”(数据行)都整齐地放在最底层的“藏书架”(叶子节点)上,并且书架之间用“绳子”(双向链表)连起来,方便按顺序找书。而所有上层目录(非叶子节点)只存编号和指向下层书架的指针。


三、为什么一个“书架”要设计成16KB这么大?

为什么不是4KB,或者64KB?这是工程师在硬件与效率间的精妙权衡。

  1. 磁盘的“最小读写单位”是块(通常4KB)。一次读16KB(4个连续块),远比读4次4KB快。如果设置太大(如64KB),单次读取得太久,而且可能读了很多没用的数据。

  2. 内存的“缓存池”有限。数据库会把常用书架(页)缓存在内存里。16KB的大小,能让内存同时缓存足够多的页,同时每页携带的数据量也足够有用。

  3. 最核心的原因:控制“树”的高度
    我们来算一笔账:

    • 一个16KB的“目录页”(非叶子节点),大约可以放下 1000多条 目录条目(比如主键ID+书架指针)。
    • 一个16KB的“藏书架”(叶子节点),假设每本书(每行数据)占1KB,那就能放 16本 书。
    • 那么:
      • 2层高的B+树:能存 1000 * 16 = 1.6万 本书。
      • 3层高的B+树:能存 1000 * 1000 * 16 = 1600万 本书。
      • 4层高的B+树:能存 1000 * 1000 * 1000 * 16 = 160亿 本书。

    看到了吗?仅仅3到4层的B+树,就能装下千万甚至百亿级的数据! 找任何一本书,最多只需要找3-4个书架(3-4次磁盘I/O)。16KB,正是在单次I/O数据量和树的高度之间找到的“黄金平衡点”。


四、终极面试题:为什么不用更简单的二叉树/红黑树?

二叉树(包括红黑树)在内存里是王者,但面对磁盘,它有致命伤。

回到图书馆比喻:

  • 二叉树/红黑树:像一个非常“高瘦”的决策树。每个决策点(节点)只分两支(左和右)。要找第1000万本书,你需要从顶层开始,做出大约24次(log₂(1000万))选择,也就是访问24个分散在不同位置的“决策点”。每次访问都可能是一次慢速的磁盘读取,总共24次I/O,慢到无法接受。

  • B+树:像一个“矮胖”的多路决策树。每个决策点(页)有几百上千个分支。要找第1000万本书,你只需要做3-4次选择(访问3-4个页),就能定位到书架。3-4次 vs 24次 I/O,这就是数量级的性能差距。

此外,B+树还有两大独家法宝:

  1. 范围查询快:因为所有“书”都在最底层的“书架”上,并且书架用绳子连着。要找编号1000到2000的所有书,你只需要找到编号1000的书架,然后顺着绳子往后扫就行。二叉树则需要不停地上下遍历,极其低效。
  2. 查询稳定:在B+树里,找任何一本书,走的“层数”都是一样的(树的高度)。而在二叉树里,找顶层的书和找最底层的书,速度天差地别。

总结一下:

  • 二叉树/红黑树:“高瘦”,适合内存小数据量,但磁盘I/O次数多,范围查询慢。
  • B+树:“矮胖”,专为磁盘设计。它利用磁盘块读取的特性,用最少的I/O次数定位数据,并且叶子节点链表让范围查询和顺序扫描快如闪电。

所以,MySQL选择B+树,不是因为它理论上的时间复杂度更优(都是O(log N)),而是因为它log的底数巨大,且其物理结构完美契合了磁盘的工作原理和数据库的查询模式。这就是它成为数据库索引标准答案的根本原因。

 

【重要内容】敬告读者 由于优快云近期将要搞事情,此专栏建议已购买的用户将内容保存到本地。尚未购买的用户请待9月1日后再决定是否需要购买。如此规则上线,本人将会关闭此专栏。并寻找其他渠道进行发布。 阅读详情

相关推荐

Ubuntu使用gstreamer开发USB相机应用(一)

Ubuntu使用gstreamer开发USB相机应用(一) 包括:gstreamer安装,测试。使用v4l2测试USB相机。使用gstreamer采集相机

Alon1787的博客 2738

Plone系统深度导览:ZODB、Catalog与工作流的三层架构解析

Plone 是一个基于 Python 和 Zope 的企业级内容管理系统,其核心区别于 WordPress 等主流 CMS 在于底层采用对象数据库 ZODB 而非关系型数据库,依赖 portal_catalog 实现高性能全文检索,并通过严格的工作流(Workflow)控制内容生命周期与权限。这种设计使 Plone 天然适配政务、金融等强合规场景,但也带来陡峭的学习曲线——理解 ZODB 的事务机制、Catalog 的索引更新逻辑、以及工作流对权限的动态覆盖,是掌握 Plone 运维与定制的关键前提。本文从

weixin_34013044的博客 375

芋道前后端分离项目跳过登录

在此页面中可以看到当在没有获取到token时,如果此页面在白名单中则直接进入,所以我们将刚刚配置在。在此路径下配置需要跳过登录的页面路径,记住path中编辑的名称。根据以上两图可以发现芋道的。将所有需要跳过登录的方法。,否则会提示登录状态过期。至此完成免登录进入页面。

FanZaiYo的博客 5485

【面试题】详细描述一条 SQL 语句在 MySQL 中的执行过程。

侦探与神秘图书馆:一条SQL语句的奇幻之旅 第一章:深夜的委托 夜已深,程序员艾伦正在调试一个紧急Bug,突然,他的屏幕上出现了一条神秘的SQL语句: SELECT book_title, author FROM magic_library WHERE category = \u0026#39;spell\u0026#39; AND

cmdos的专栏 40

加湿器方案-DLT8M04TS-杰力科创

基本组成: 一个触摸按键、一组RGB灯、一个雾化片、一个充电IC。 产品功能: 第一次上电光机状态,RGB红/绿/红灯依次闪烁灭; 2、按键功能:短按开关机和三档喷雾工作模式,第一次短按持续喷雾,短按第二次喷3S,停3S,短按第三次关闭喷雾模式,依次循环; 在喷雾或是不喷雾的状态下长按1.5S RGB灯渐变,一直循环,第二次长按当前灯光闪烁一下常亮,第三次长按关机; 3、持续喷雾定时5小时自动断电,间歇喷雾定时10小时自动断电,若在间歇工作时有切换为持续喷雾,那间歇喷雾的...

JLKCsz的博客 512

宝塔面板一键部署Z-Blog博客 - 内网穿透实现公网访问

Ubuntu系统作为Linux系统的一个重要分支,既有Linux系统的轻量化、高扩展性和长时间稳定运行,也拥有Windows一样的友好图形界面,因此可以作为熟悉服务器系统的良好选择。对于笔者来说,ubuntu系统最大的用处,就是可以让家里老旧的电脑重焕生机,让本已退居二线的电脑与cpolar内网穿透软件搭配,成为私人服务器,搭建自己喜欢的各种网站。今天,笔者就为大家介绍,如何使用cpolar内网穿透+Z-blog搭建私人博客网站。

m0_74808907的博客 3147

MySQL事务隔离级别实现原理:用生活例子讲透,小白3分钟看懂

我们开一家「小明奶茶店」,用一张orders现在有两位店员(事务A和事务B)同时工作——这就是并发。

Java_Chuck的博客 2247

YOLOv8与注意力机制融合:EMA(高效多维注意力)的原理剖析与实战应用

本文介绍了如何在YOLOv8目标检测模型中集成EMA(高效多尺度注意力)机制。主要内容包括:EMA注意力机制的工作原理解析,展示其多尺度特征融合和高效计算特性;详细的环境配置与依赖安装指南;EMA模块的完整代码实现,包含分组处理、空间注意力权重计算和特征融合等关键步骤;以及将EMA集成到YOLOv8网络结构的方法。通过添加EMA模块,可以提升模型对关键特征的关注能力,有效抑制背景干扰,从而增强目标检测性能。本教程提供了从原理到实现的完整解决方案。

m0_64661770的博客 147

Kafka消息不丢失全攻略

环节核心目标关键配置/动作说明与影响生产者确保消息成功送达Broker并持久化acks=all最高可靠性保证,等待所有ISR副本确认。防止网络重试导致重复开启幂等生产者,实现精确一次语义。应对临时故障retries设为较大值配合,自动重试可恢复的失败。可靠发送方式使用异步发送并监听回调,处理异常。Broker数据冗余,防止单点故障多副本机制是数据高可用的基础。定义持久化成功的标准与acks=all配合,确保写入足够多的副本。消费者避免消息未处理就被认为已消费必须关闭,采用手动提交。

Java_Chuck的博客 441

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

计算机组成原理(第三版)唐朔飞-第十章控制单元的设计-课后习题

weixin_45735391的博客 3万+

数字电路与逻辑设计实验二 组合逻辑电路

1.组合逻辑电路功能测试 (1)用 2 片 74LS00 组成图 2.1 所示逻辑电路。为便于接线和检查,在图中要注明 芯片编号及各引脚对应的编号。 (2)图中 A、B、C 接逻辑开关,Y1,Y2 接发光管电平显示。 (3)按表 2.3 要求,改变 A、B、C 输入的状态,填表并写出 Y1,Y2 的逻辑表达式。 (4)将运算结果与实验结果进行比较。 2.测试用异或门(74LS86)和与非门组成的半加器的逻辑功能。 根据半加器的逻辑表达式可知,半加 器 Y 是 A、B 的异或,而进位 Z 是 A

欢迎交流学习心得 1277

一条SQL执行过程:从查询到结果的奇幻之旅

这个顺序永远不会改变,就像做菜必须先备料再烹饪一样。

Java_Chuck的博客 404

RKNN 端侧部署必看:YOLOv11 Pose 姿态估计模型转换与性能优化实战

随着人工智能技术在边缘计算领域的快速发展,姿态估计作为计算机视觉的重要分支,在智能监控、人机交互、体感游戏等场景中展现出巨大的应用潜力。本文深入研究了YOLOv11 Pose模型在Rockchip RKNN平台上的部署方案,从理论基础、模型转换、平台优化到实际部署进行了全面阐述。通过详细的技术分析和实验验证,证明了RKNN平台能够有效提升YOLOv11 Pose的推理性能,在RK3588硬件平台上实现了高达100 FPS的实时姿态检测,为边缘计算场景下的姿态估计应用提供了高效的解决方案。

m0_71589036的博客 183

Redis高频面试题核心机制深度解析:速度之源、内存淘汰与持久化实战

Redis之所以能在十几年间保持其领先地位,不仅因为其极致的性能,更因为其不断演进的设计哲学。从单线程到多线程I/O,从简单的LRU到智能的LFU,从RDB/AOF二选一到混合持久化,每一次演进都体现了工程上的务实与智慧。在实际应用中,没有"最好"的配置,只有"最适合"的配置。理解业务的数据访问模式,监控系统的实际表现,才能做出最合理的技术选择。希望本文能帮助你在Redis的深度使用上更进一步,构建出更稳定、高效的系统。参考资料《Redis设计与实现》

Java_Chuck的博客 374

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

永不忘算法:三数之和的“双指针”魔法

排序:这是双指针法的前提,没有排序就没有方向感。定一移二:先定住第一个数,剩下的用两个指针从两头往中间凑。去重:选队长时看前一个,移动指针时看下一个,只要数字一样就跳过。这就是“三数之和”的奥秘。你学会了吗?

Java_Chuck的博客 349

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Redis集群高频面试题全解析:从入门到精通,一篇文章搞定!

Redis槽(Slot),通常称为哈希槽,是Redis集群实现数据分片(Sharding)的核心机制。简单来说,它就像一个大仓库的16384个编号货架,每个货架都有固定的管理员(Redis节点)。逐步提问Q1:槽的数量是固定的吗?A:是的,固定16384个(0-16383)Q2:为什么是16384,不是10000或20000?网络通信效率:集群节点间需要同步槽分配信息16384个槽用2KB内存就能存储(16384/8=2048字节)如果65536个槽,需要8KB,网络传输和内存占用都翻4倍。

Java_Chuck的博客 349

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

分布式事务最佳实践:基于kafka实现的最终一致性方案

在真实实践中,为了提升消息实时性,在业务与消息事务提交后立即触发MQ投递是一种有效的优化模式。其最佳实践是结合与@Async,它既保证了触发时机与事务成功提交的严格绑定,又通过异步执行避免了对主流程的性能影响。然而,这种模式并未改变最终一致性的本质,只是缩短了不一致状态的时间窗口。必须通过生产者重试、消费者幂等、兜底定时任务补偿以及完善的监控告警这一整套“组合拳”,来应对网络不可靠、服务抖动等分布式环境中的固有挑战,从而在享受低延迟好处的同时,确保系统的最终数据一致性。

Java_Chuck的博客 344

精准定位Direct Buffer OOM的体系化排查实践

针对这类堆外内存泄漏问题,其隐蔽性高于堆内泄漏,排查必须遵循从宏观监控到微观代码的体系化路径。以下是结合生产实践的完整排查方案。生产环境的集中监控是发现问题的第一道防线,它能提供泄漏的,通常无法直接定位根因。通过JMX Exporter或Micrometer暴露JVM的监控仪表盘只能回答,例如“直接内存使用率在03:00后持续攀升”。但它无法回答,即无法告诉你是哪段代码、哪个对象持有了这些未被释放的。因此,监控告警是。当监控告警后,需要登录问题实例进行深度诊断。仅依赖参数是远远不够的。

Java_Chuck的博客 290

分布式事务: 主流最终一致性方案对比

分布式事务的最终一致性方案旨在确保在分布式系统中,所有参与方最终将达到一致的状态,尽管在过程中可能存在短暂的不一致。这种模型在保证系统可用性和分区容错性的同时,牺牲了强一致性的实时性要求。以下是几种主流的最终一致性方案的汇总与详解。

Java_Chuck的博客 282

JVM内存模型与垃圾回收全解析

这是JVM在运行Java程序时,对物理内存的逻辑划分,是。JMM是一个,定义了Java程序中共享变量的访问规则,旨在解决多线程环境下的问题。它规定了线程如何与主内存及工作内存进行交互。lockunlockreadloaduseassignstorewritevolatilei++finalfinal这是判断对象是否存活的。以一系列“GC Roots”对象为起点,向下搜索,形成引用链。任何到GC Roots的对象,即为不可达,可被回收。这是。

Java_Chuck的博客 225

线上告警!Kafka积压百万消息,我们是这样快速止血的

通过编写代码将积压消息转发到高分区新主题,并配套弹性临时消费者的方案,是一种经典的“空间换时间”和“解耦”的应急处理模式。它通过架构上的隔离与资源的弹性投入,能够快速形成对海量积压消息的“消化能力”,为后续根因排查和系统修复赢得宝贵时间窗口,是处理Kafka百万级消息积压中最主流且有效的技术手段之一。

Java_Chuck的博客 220

Java heap space OOM 精准定位与体系化排查方案

可视化工具将二进制的堆快照转化为直观的图表和引用关系图,让开发者能够。

Java_Chuck的博客 184

MySQL建库建表操作学习笔记

SQL(Structured Query Language,结构化查询语言)是用于在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。:用于定义对数据库对象(库、表、列、索引)的操作,如 CREATE、DROP、ALTER、RENAME、TRUNCATE 等。保存可变长度的字符串(可包含字母、数字以及特殊字 符)。:用于定义对数据库记录的操作,如 INSERT、DELETE、UPDATE、SELECT 等。:用于定义对数据库、表、字段、用户的访问权限和安全级别,如 GRANT、REVOKE 等。

Eternitycai的博客 222

MySQL 索引深入理解:B+ 树、二级索引、联合索引与查询优化

理解二级索引后,就可以理解回表了。SELECT *MySQL 的执行过程分为三个步骤。覆盖索引(Covering Index)并不是一种独立的索引类型,而是一种查询效果。SQL 查询需要的所有字段,都能够直接从某个索引中获得,不需要再访问聚簇索引获取其他字段。例如:因为user_id已经包含在二级索引中,所以 MySQL 可以直接返回结果。不需要回表。联合索引(Composite Index)是同时使用多个字段建立的索引。它的排序规则是:首先按照user_id排序。当user_id。

m0_64642997的博客 109

MySQL 单点详解(14)

给定一条 SQL,联合索引的列该怎么排呢?

2401_88601046的博客 344

MySQL 的 REPEATABLE READ 到底能不能防幻读——从快照读、当前读到 Next-Key Lock

本文系统讲解 InnoDB 可重复读级别下的幻读问题:从三类读异常切入,剖析快照读依赖 MVCC、当前读依赖 Next-Key Lock 的双防线机制,用双会话实验复现幻读仍会出现的边界场景,并解释各数据库在幻读防护上行为分歧的根源。

大模型全栈工程师 · Thanks_ks 294
上一篇: 永不忘算法:三数之和的“双指针”魔法
下一篇: Redis分布式锁:从Setnx到RedLock的深度解析
路飞说AI
博客等级 码龄10年 214粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值