这篇笔记想把两件事说清楚索引的结构到底长什么样、什么场景下真的能用上。这两点想通了“最左前缀”“回表”覆盖索引这些概念就不用死记靠推理就能得出结论。目录为什么需要索引索引如何演化成 B 树聚簇索引与二级索引索引不是免费的午餐B 树索引能用上的场景回表的代价与覆盖索引挑选和设计索引的经验一、为什么需要索引InnoDB 的每个数据页内部靠页目录 二分查找能很快定位到记录但页与页之间只是通过双向链表相连物理位置上并不连续。这就带来一个问题按主键查询页内可以二分查找但要先知道记录在哪一页——没有索引时只能从第一页开始顺着链表逐页查找。按其他列查询情况更差页内没有为非主键列建立目录只能从头到尾逐条记录比对。表的数据量小的时候还好一旦上到千万级这种从头扫到尾的方式基本无法接受。于是就需要一种能跳过大部分无关页面、直接定位到目标数据的机制——这就是索引。二、索引如何演化成 B 树理解索引结构关键的一步是先设想一个最朴素的方案给所有数据页建一个目录每条目录项记录该页最小的主键值 页号把这些目录项连续存放对目录本身做二分查找两步就能定位到记录。但这个方案有两个问题一个数据页最大只有 16KB表越来越大时目录项本身也会多到一页装不下——连续存放这个前提就不成立了。记录频繁增删时目录项也要跟着变动。中间删掉一条后面的目录项都要往前移动维护成本很高。InnoDB 的解决办法是直接复用存储用户记录的那套数据页结构来存储目录项本身。目录项被当作一种特殊记录处理记录头里的record_type 1用于标识同样能享受页目录 二分查找的机制。当一页装不下所有目录项时就分裂出新页上层再生成一层目录项的目录项——这样逐层往上叠加最终就形成了一棵倒置的树这就是B 树。下图是简化版结构假设每页只放 2~3 条记录实际场景中一页能放几百上千条B 树也就用不着长这么多层图中实线箭头是父子指针代表上层目录项指向下一层的具体页面虚线是双向链表代表同一层的页面前后相连。关键结论最底层第 0 层存放的是真正的用户记录称为叶子节点上面几层存放目录项记录称为内节点。有一点需要记住根节点自诞生起页号就不再变化。系统只需记住这个根页号就能顺着它找到任何数据。另外二级索引的内节点不能只保存索引列 页号否则索引列值相同时无法判断新记录该分到哪个子页——所以实际保存的是索引列 主键 页号三元组确保同一层的记录彼此可以区分。此外一个页最少要存 2 条记录否则树会退化成一条链表也就失去了索引的意义。按这个结构推算假设叶子节点能存 100 条记录内节点能存 1000 条目录项B 树 3 层就能容纳 1 亿条记录4 层能容纳千亿级——这就是索引查找只需几次 I/O的原因。三、聚簇索引与二级索引InnoDB 里每建一个索引就对应一棵独立的 B 树但按叶子节点存储内容的不同可以分成两类聚簇索引二级索引排序依据主键值索引列的值叶子节点内容完整的用户记录含所有列索引列 主键值建立方式InnoDB 自动创建无主键会隐式生成需显式CREATE INDEX数量每张表唯一一个可以建多个这里有一点容易被忽略但很重要在 InnoDB 里索引就是数据本身——聚簇索引的叶子节点直接就是数据的存储方式而不是额外的一份查找结构。二级索引的叶子节点只保存索引列 主键所以要拿到完整记录还需要拿着这个主键再查一次聚簇索引这个过程称为回表。之所以要付出回表这一次额外开销是因为如果每建一个索引都把完整记录再拷贝一份存储空间的开销会很大得不偿失。联合索引本质上仍是一棵二级索引 B 树只是排序规则变成先按第一列排序第一列相同时再按第二列排序依此类推。它和给几个列分别建索引完全是两回事——联合索引从头到尾只对应一棵树。题外话 · MyISAMMyISAM 走的是另一条路——数据文件和索引文件分开存储包括主键索引在内所有索引都只保存索引列 行号查询时同样要回表一次相当于 InnoDB 里所有索引都是二级索引的效果。四、索引不是免费的午餐建索引是有代价的主要体现在两方面空间上每建一个索引就要多生成一棵 B 树每个节点都是实打实的数据页占用存储空间。时间上每次增删改都要维护索引这棵树的排序关系可能触发页分裂、记录移位索引建得越多写入性能损耗越大。所以是否要为某列建索引还得结合下面这些能否用上索引的场景来判断。五、B 树索引能用上的场景以一个三列联合索引为例KEYidx_name_birthday_phone_number(name,birthday,phone_number)全值匹配WHERE 条件把索引里的列都用上了写在前面还是后面并不影响结果查询优化器会自动调整比较顺序。匹配左边的列最左前缀原则条件只包含索引最左边连续的几列比如只有name或者name birthday也能用上对应前缀部分的索引但如果中间跳过了一列只给name和phone_number中间的birthday缺失后面的列就用不上了。匹配列前缀字符串本身按前缀排好序所以name LIKE As%这类前缀匹配能用上索引但LIKE %As%或纯后缀匹配就不行可以考虑把字符串反转存储把后缀匹配转换成前缀匹配。匹配范围值范围查询只有最左边那一个参与范围比较的列能用上索引后面的列即使也在联合索引里也无济于事——因为范围过滤后的记录不再保证按后面那一列排好序。精确匹配 范围匹配组合前面的列都是等值匹配时紧跟着的一列做范围查询依然可以用上索引——先靠等值把范围收窄再在这个已排好序的小范围内做区间扫描。用于排序ORDER BY的列顺序如果和索引列顺序一致可以省去一次额外的文件排序filesort。前提是各列排序方向要一致不能 ASC、DESC 混用、排序列要来自同一个索引、且索引列不能被函数或表达式包裹。用于分组GROUP BY的列顺序与索引列顺序一致时同样可以省去在内存中分组的开销。六、回表的代价与覆盖索引二级索引的扫描是顺序 I/O索引列本身有序物理上也相邻而回表去聚簇索引取数据往往是随机 I/O主键值不连续。需要回表的记录越多走二级索引这条路就越不划算——极端情况下优化器甚至会放弃索引直接走全表扫描。这也是为什么LIMIT常常能让优化器更倾向于选择二级索引 回表需要回表的记录数变少了。要彻底避免回表可以使用覆盖索引查询列表里只写索引已经包含的列避免使用SELECT *这样二级索引查出的数据就已经够用不必再回聚簇索引查一次。七、挑选和设计索引的经验只为出现在WHERE、连接条件、ORDER BY、GROUP BY中的列建索引单纯出现在查询列表里的列不需要建索引。优先为基数大的列不重复值较多的列建索引——基数太小比如性别、状态位这类只有两三个取值的列索引的过滤效果有限回表比例也可能偏高。索引列的类型尽量选小能用INT就不用BIGINT主键尤其如此因为所有二级索引的叶子节点都会带一份主键值——主键类型越大所有二级索引也会跟着变大。长字符串列可以只索引前缀比如name(10)节省空间、加快比较速度但前缀索引会导致无法用索引完成排序前缀相同、后续字符不同的记录先后顺序无法确定。索引列必须单独出现在比较表达式中一旦被函数或运算包裹比如my_col * 2 4索引就会失效。主键最好使用AUTO_INCREMENT递增生成乱序插入主键容易导致数据页频繁分裂、记录移位自增主键则始终追加到最后一页性能更稳定。定期检查是否存在冗余索引比如已有(name, birthday)联合索引又单独建了(name)和重复索引同一列既是主键又建了唯一索引/普通索引这类索引只会增加维护成本没有额外收益。版本提示B 树索引的底层结构在 MySQL 5.7 和 8.0 上完全一致。8.0 在使用层面新增了几个实用特性降序索引INDEX (a DESC)真正生效5.7 里写了也是忽略的、不可见索引INVISIBLE让优化器暂时看不见某个索引用来灰度验证删了它会不会变慢而不用真删、函数索引可以直接给LOWER(name)这类表达式建索引绕开函数包裹列导致索引失效的限制。理解 InnoDB 索引的核心是抓住B 树如何从一个简单的页目录演化而来这条主线根页面不变、二级索引带主键、回表、最左前缀——这些都是这棵树的结构性质带来的自然结果而非人为规定的规则。想清楚这条推导过程索引能不能用上就变成了一个可以自行推理出的问题而不必依赖死记硬背。
Unity高性能多实例RTSP/RTMP流媒体播放器架构与实现 1. 项目概述:为什么Unity需要高性能流媒体播放器?在数字孪生、虚拟仿真、安防监控、在线教育乃至互动直播等领域,Unity引擎的应用边界早已超越了传统的游戏开发。一个越来越普遍的需求是:在Unity构建的3D场景中,实时接…
小孩也能看懂的算法笔记,排序day3-图解快速排序内存流转 算法的时间是怎么得出的? 计算机执行所有算法时,都在重复:取数据运算算完存回去。 算法的时间复杂度就是计算机读取数据运算算完再存回去的次数。 还记得为什么要先了解数据结构吗?小孩能看懂的算法笔记首篇 那数据在存储中是…
使用Xilinx FPGA完成HDMI LOOPBACK回环显示设计(五) [5]phsaligner模块<1>此模块通过输出IDELAY和ISERESE两个模块的控制信号,完成phase alignment.<2>状态机的运行是本模块的核心.这一部分完全应用1-3-(4)-[2]小节介绍的思路.<3>在没有接收到control token时,首先尝试bitslip操作.尝试过所有的bitslip后,再进行…
python class attr 凌晨2点崩溃后,他怒撕Python class attr的假技巧,真相扎心了 一、凌晨2点崩溃后,他撕开了技巧的“谎言”认准每一位学习者, 都历经这般状况: 收罗了上百篇“资深开发者私藏窍门”, 熬夜研读并书写满满笔记, 然而实际应用于项目之时, 不是不适应, 就是全然没成效, 反倒越改越糟。曾有那么一位程序员, 不慎掉进这样的陷阱之中, 于…
OpenAI桌面端多Agent语音控制:重构AI工作流协作新范式 如果你还在为每次切换不同AI助手而烦恼,或者觉得语音交互只能完成简单问答,那么OpenAI桌面端的最新更新可能正是你需要的解决方案。最近上线的语音控制多Agent功能,正在重新定义我们与AI的交互方式——从单一对话转向真正的智能工作流协同。传…
降维算法75倍加速:从PCA到稀疏字典学习的工程实践 # 降维算法75倍加速:从PCA到稀疏字典学习的工程实践## 背景:高维数据下的性能瓶颈在机器学习工程中,特征维度爆炸是常见痛点。无论是图像处理(如CNN之前的特征提取)、NLP中的词嵌入降维,还是推荐系统中的用…
AI视频生成器技术选型与工程实践指南(2026) # AI视频生成器技术选型与工程实践指南(2026)## 1. 背景与挑战2026年,AI视频生成技术已从“玩具”演变为企业级生产力工具。Tracxn最新报告显示,Synthesia、Lightricks、Twelve Labs、Runway、OpusClip等公司已成为该领域头部玩家…
2026沈阳自建房供应商推荐:专业品质与东北地域化设计、暖通系统适配分析 - 卓企推荐 导语:东北自建房市场的核心挑战与选型逻辑 沈阳作为东北地区核心城市,其自建房市场正经历从“粗放建造”向“精细化、专业化”的转型。2026年,随着东北严寒气候对建筑保温、暖通性能要求的持续提升,以及沈阳城市更…
电脑上怎么进行pdf合并?实测7种方法,免费又好用 - AI测评专家 签完租房合同那会儿,中介一口气发来三个 PDF:合同正本、附加条款和家具清单。房东要求合并成一个文件再回传,我当时手边电脑没装任何 PDF 软件,差点跑去楼下打印店。后来这一年多试了不少方案,才发现合并 PDF 这事…
SolidWorks许可证预测优化:数据驱动降本增效 1. 项目背景与核心价值在工业设计领域,SolidWorks作为三维CAD软件的标杆产品,其许可证管理一直是企业IT成本管控的痛点。某中型制造企业曾因许可证短缺导致项目延期,而另一家则因过度采购造成每年近20万元的资源浪费——这正是我们开发这套预…
OpenClaw开源智能体网关:AI助手与即时通讯的完美融合 1. 项目概述:当AI助手遇上即时通讯上周在调试一个自动化工作流时,我突然意识到:如果能把AI助手直接集成到日常使用的聊天软件里,很多重复性工作就能在对话中一键完成。这个想法促使我找到了OpenClaw——一个开源的智能体网关项目&…
【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制) 博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集 Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…
智慧飞行 大疆无人机一站式智能管控平台/支持大疆机场/私有化部署 从航线规划、自动飞行、AI识别到数据管理,一个平台全搞定 智慧飞行-大疆无人机一站式智能管控平台/支持大疆机场/私有化部署 企业级全域智能无人机一体化管控平台源码! 专为电力巡检、安防监控、应急救援、测绘勘察等行业打造,让您的无人机舰队实现 “无人化、自动化、智能化” 管理! 🎯 …
揭秘ChatGPT+Mathematica协同教学:为什么92%的初学者在72小时内建立函数直觉? 更多请点击: https://codechina.net 第一章:AI帮助理解数学概念 人工智能正以前所未有的方式重塑数学学习的路径。通过自然语言处理与符号计算的深度融合,AI不仅能解析抽象定义,还能将定理、证明和几何直觉转化为可交互、可验证的…
[C++]内存管理:串顺序存储的内存回收 在串(字符串)的顺序存储中,内存回收的方式取决于字符串的存储方式以及所使用的编程语言和相关库。以下以 C 为例进行说明,因为 C 对内存管理有较为直接的控制。 1. 基于 char 数组的串顺序存储 如果使用普通的 char 数组来存储字…
移动端游戏功耗测试实战:电流、功率、亮度和场景对比 移动端游戏功耗测试:先控制变量,再比较优化是否真的省电 摘要:功耗测试最容易犯的错误,是拿两次不同温度、不同亮度、不同场景的平均功率直接比较。本文给出一套可复现的游戏功耗测试方法,覆盖引擎特性验证、版本回归和黑盒体验测试,并说明如何把功耗与帧率、温控、CPU/G…
足球口袋教练 HarmonyOS 离线应用实战(03/20):ArkUI 首页仪表盘搭建 本文是“足球口袋教练 HarmonyOS 离线应用实战”系列第 3 篇。示例项目是一个 HarmonyOS / ArkTS / ArkUI 编写的离线足球训练助手,围绕真实页面、真实截图和可复现操作展开。 本篇要解决的问题 训练 App 的首页不能只展示欢迎语,它要解决“我现在该点哪…