MySQL 实战宝典(五):MySQL 索引——从 B+ 树原理到实战优化

Mysql高级篇(中)—— 索引优化 MySQL索引失效的场景、案例分析及如何优化索引 阅读详情

一、 什么是索引?

索引(Index) 是帮助 MySQL 高效获取数据的排好序的数据结构。如果把数据库表比作一本书,索引就是书的目录,它能让你在海量数据中快速定位到所需内容,而无需翻阅整本书(全表扫描)。

由于数据量通常很大,索引无法全部加载到内存,因此索引往往以索引文件的形式存储在磁盘上。

1. 聚簇索引 vs 非聚簇索引

InnoDB 存储引擎根据索引的物理存储方式,将索引分为两类:

索引类型别名描述叶子节点存储内容是否需要回表
聚簇索引主键索引每张表有且仅有一个。表数据本身就是按 B+ 树组织存储的。完整的行记录(所有列)否
非聚簇索引二级索引 / 辅助索引可以有多个。索引列的值 + 主键值是(除非是覆盖索引)

🔍 图解:两种索引的区别

  • 聚簇索引(Clustered Index):
    找到叶子节点,就直接拿到了所有数据。
    聚簇索引示意图

  • 非聚簇索引(Secondary Index):
    找到叶子节点拿到主键 ID,再去聚簇索引中查数据的过程,称为回表。
    非聚簇索引示意图

2. 联合索引

针对多个列(如 col1, col2)构建的索引。排序规则为:先按 col1 排序;在 col1 相同的情况下,再按 col2 排序。


二、 核心原理:为什么选择 B+ 树?

数据库的读取是以页(Page) 为单位的(通常 16KB)。索引设计的目标是:在尽可能少的磁盘 I/O 次数内找到目标数据。

我们来看看不同数据结构的表现:

1. 为什么不用二叉查找树 / 红黑树?

  • 结构问题:树太高(瘦高型)。
  • I/O 瓶颈:二叉树每个节点只能存一个数据。对于千万级数据,树的高度会非常高,导致每一次查询都要进行大量的磁盘 I/O 操作,性能极差。

二叉树

2. 为什么不用 B 树(B-Tree)?

B 树虽然是多叉树(矮胖型),但它有一个特点:非叶子节点也存储数据(行记录)。

  • 缺点 1:路数变少。由于数据页大小是固定的(16KB),如果节点存了很大的行数据,那么能存的索引指针就变少了,树就会变高,I/O 增多。
  • 缺点 2:范围查询困难。叶子节点之间没有指针连接,范围查询需要反复回溯遍历。

B树

3. 为什么 B+ 树是神?

B+ 树是对 B 树的升级版,完美契合数据库查询场景:

  1. 更矮更胖:非叶子节点只存索引(key),不存数据。一个节点能塞下更多的索引值,使得整棵树的层级非常低(通常 3 层就能存千万级数据)。
  2. 查询稳定:所有数据都在叶子节点,查询路径长度一致。
  3. 天生支持范围查询:叶子节点之间通过双向链表连接,范围查询只需定位起点,然后顺着链表遍历即可。

B+树


三、 MySQL 索引实战

1. 索引创建演示

CREATE TABLE student (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- 聚簇索引
    `name` VARCHAR(10) NOT NULL,
    `gender` CHAR(1) NOT NULL,
    `address` VARCHAR(100) NOT NULL,
    KEY `idx_name_gender` (`name`, `gender`) -- 联合索引(非聚簇)
);

💡 最佳实践:为什么建议使用自增主键?

  1. 存储效率:自增 ID 占用空间小,B+ 树非叶子节点能存更多指针,树更矮。
  2. 写入性能:自增 ID 保证了写入是顺序追加,避免了随机写和页分裂带来的性能损耗。

2. 最左前缀原则(核心规则)

对于联合索引 (col1, col2, col3),B+ 树是按照从左到右的顺序建立的。索引匹配必须严格遵循“从左到右,不能跳过”的原则。

(1) 字段顺序匹配

  • ✅ WHERE col1='a' AND col2='b' -> 命中 (col1, col2)
  • ✅ WHERE col2='b' AND col1='a' -> 命中 (MySQL 优化器会自动调整顺序)
  • ❌ WHERE col2='b' -> 失效 (跳过了 col1,没法查)
  • ⚠️ WHERE col1='a' AND col3='c' -> 部分命中 (只用到了 col1,col3 无法使用索引)

(2) 字符串模糊匹配

  • ✅ LIKE 'abc%' -> 命中 (前缀确定,是有序的)
  • ❌ LIKE '%abc' -> 失效 (前缀未知,无序)

(3) 范围查询的中断

如果中间某个字段使用了范围查询(>, <, BETWEEN, LIKE),则其右边的列无法使用索引。

  • WHERE col1='a' AND col2 > 10 AND col3='c'
    • col1:命中
    • col2:命中
    • col3:失效 (因为 col2 是范围,导致后面的 col3 在 B+ 树中不再有序)

3. 索引失效的常见场景

场景原因示例
计算/函数索引是对原始值建立的,计算后无序WHERE YEAR(create_time) = 2023
类型转换隐式转换会导致全表扫描字符串字段不加引号:WHERE name = 123
最左前缀断裂见上文WHERE age = 18 (索引是 name_age)
OR 条件OR 两边只要有一个没索引,就会全表扫描WHERE id = 1 OR age = 18 (age 无索引)
不等于!= 或 <> 无法精确命中,通常走全表WHERE name != 'Tom'

四、 索引设计最佳实践

在实际开发中,建立索引需要权衡“查询性能”与“维护成本”。

  1. 覆盖索引 (Covering Index) 🔥

    • 尽量让 SQL 查询的字段都包含在联合索引中。
    • 效果:直接在二级索引中就能查到结果,避免回表,性能极高。
    • 例:SELECT name, gender FROM student WHERE name='Tom',正好命中 idx_name_gender,无需回表。
  2. 避免 SELECT *

    • SELECT * 几乎必然导致回表,且传输大量无用数据,浪费 I/O 和带宽。
  3. 高区分度原则

    • 只为区分度高(唯一值多)的列建索引。
    • 反例:不要为 gender(只有男/女)单独建索引,因为过滤后数据量依然很大,MySQL 可能直接走全表扫描。
  4. 字符串前缀索引

    • 如果字符串很长(如文章标题),可以只对前 N 个字符建索引:CREATE INDEX idx_title ON table(title(10))。
  5. 控制数量

    • 索引不是越多越好。每个索引都需要占用磁盘空间,且每次 INSERT/UPDATE/DELETE 都要维护索引树,过多的索引会降低写入性能。

参考资料

MySQL 索引优化详解 当一个索引包含了查询所需的所有字段时,这个索引就被称为覆盖索引。在执行查询时,MySQL 可以直接从索引中获取结果,而不需要访问表数据。这不仅减少了 I/O 操作,还提高了查询效率。MySQL 索引优化是数据库性能优化的重要部分,通过合理使用索引、利用覆盖索引、以及掌握索引合并技术,可以显著提升查询性能。在设计索引时,既要考虑查询的频率和复杂度,也要兼顾写入性能的影响。在实际应用中,结合业务需求和查询模式,选择适当的索引优化策略,是提升 MySQL 数据库性能的关键。 阅读详情

相关推荐

Java面试宝典:MySQL索引

和慢日志分析,避免过度索引导致写入性能下降。在大数据场景下(亿级数据),建议采用。、全文索引、哈希索引三种核心类型,其中B+树索引是事务处理和复杂查询的基石。图示:聚集索引的叶子节点直接包含行数据。图示:辅助索引通过主键关联聚集索引。图示:三星索引的覆盖与排序设计。图示:联合索引的多级排序机制。InnoDB存储引擎支持。主键范围查询极速响应。排序操作免额外I/O。主键更新需数据行移动。

搬砖的小熊猫的博客 164

MySQL索引优化(超详细)

MySQL索引优化,涉及到索引介绍,性能分析,查询优化,慢查询日志。

weixin_55816781的博客 9379

浙政钉H5应用上架实战:从环境配置到发布避坑指南

本文详细解析浙政钉H5应用上架全流程,从环境配置到发布避坑指南。重点介绍Vue 2.6 + Node 14.21.3的稳定开发环境搭建、项目结构规范及常见报错解决方案,帮助开发者高效完成浙政钉H5应用上架流程。

weixin_27943395的博客 286

MySQL索引优化

这里说一下几种常见优化索引的方法:前缀索引顾名思义就是使用某个字段中字符串的前几个字符建立索引,那我们为什么需要使用前缀来建立索引呢?使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。不过,前缀索引有一定的局限性,例如:覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表

mz474920631的博客 1万+

避开这些坑!Kaggle数据集下载常见问题及解决方案(含Header Editor插件配置)

本文针对Kaggle数据集下载过程中的常见难题,提供了系统性的解决方案。重点解决了验证码无法显示、API安装失败、密钥文件配置错误及下载命令执行问题,并详细介绍了使用Header Editor插件配置请求头以绕过验证码障碍的实战方法,帮助用户高效获取数据。

weixin_29043895的博客 301

对工时评估的思考:当AI颠覆了coding效率

在AI时代,“人日”作为软件工时度量衡已然失效。开发的价值核心正从“编码实现”转向“深度思考”与“精准沟通”——即如何将人类的模糊需求精确地传达给AI。当最有价值的“思想工作”变得最难量化时,传统的项目管理范式随之动摇。我们必须超越对过程的算计,开始探索衡量思想、沟通与业务价值的新标尺。

架构师刘7的博客 1017

mysql处理百万级数据库常识(转载)

最近一段时间参与的项目要操作百万级数据量的数据,普通SQL查询效率呈直线下降,而且如果where中的查询条件较多时,其查询速度简直无法容忍。之前数据量小的时候,查询语句的好坏不会对执行时间有什么明显的影响,所以忽略了许多细节性的问题。       经测试对一个包含400多万条记录的表执行一条件查询,其查询时间竟然高达40几秒,相信这么高的查询延时,任何用户都会抓狂。因此如何提高sql...

wb284551926的博客 967

SAP PFCG 中的单一角色与复合角色

在 SAP 系统的安全与授权管理中,事务码 PFCG(角色维护)扮演着关键角色。理解单一角色(Single Role)和复合角色(Composite Role)的概念,对于有效地管理用户权限至关重要。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1477

【MySQL 数据宝典】【索引原理】- 001 索引原理分析 (AVL树、B-Tree、B+Tree)

B-Tree是一种平衡的多路查找树,B树允许一个节点存放多个数据. 这样可以在尽可能减少树的深度的同时,存放更多的数据(把瘦高的树变的矮胖)B-Tree中所有节点的子树个数的最大值称为B-Tree的阶,用m表示.一颗m阶的B树,如果不为空,就必须满足以下条件.m阶的B-Tree满足以下条件:每个节点最多拥有m-1个关键字(根节点除外),也就是m个子树根节点至少有两个子树(可以没有子树,有就必须是两个)分支节点至少有(m/2)颗子树 (除去根节点和叶子节点其他都是分支节点)

黄金时代的架构之路 950

精通 Android NDK/JNI:从入门到精通实战与面试精粹

在Android开发中,

郑伟强dev的专栏 144

用 MVC 框架把 ABAP 报表写成可扩展的应用(2)

本文介绍了一个基于MVC架构的SAP报表模板,解决了传统ABAP报表开发中的三个核心痛点: 选择屏幕校验逻辑分散问题 - 通过统一的选择屏幕控制器集中管理校验逻辑 在线与后台输出不一致问题 - 共享同一数据模型,通过不同控制器实现多样化展示 屏幕流转管理混乱问题 - 主控制器统一管理所有屏幕流程和事件 该模板采用分层架构: Model层专注数据获取和业务规则 Controller层管理流程和交互 View层负责展示逻辑 特别适用于需要同时支持交互式ALV展示和后台批处理输出的报表场景,通过标准化的扩展点设计

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 78

mysql通关面试宝典

文章目录1.mysql事务的常见异常和隔离级别2.mysql的B树索引,B+树索引,哈希索引原理。2.mysql的引擎3.mysql中为什么用B+树4.讲一讲索引,最左匹配原则(最佳左前缀)5.什么是SQL注入,怎么预防6.你对mysql了解有多少(讲了innodb、myiasm两个引擎的区别,隔离级别,索引,使用B+树的优势,最左匹配原则,MVCC)7.怎么对sql进行分析(explain和show profile)7.1 explain的字段7.2 show profile9.数据库全局锁10.索引优化

JH灰色的博客 3319

电池管理系统(BMS)技术全景解析:从基础原理到智能未来

《BMS技术演进与核心功能解析》摘要: 电池管理系统(BMS)作为新能源系统的智能中枢,已从基础保护电路发展为具备预测能力的智能系统。文章系统梳理了BMS三大技术时代:1.0保护时代(1990-2000)采用硬件保护电路;2.0智能时代(2000-2020)引入SOC算法;3.0云脑时代(2020后)实现AI预测。详细解析了BMS三大核心模块:AFE感知系统(±2mV精度)、功率驱动模块(10μs级保护)和均衡技术(效率提升至85%),并对比了主动/被动均衡技术差异。同时阐释了SOC/SOH等关键参数定义与

bother3000的博客 2984

成大事数据库技术面试题系列04:MySQL索引深入面试题 | 第1-10题 | 从B+树原理到索引优化,成为数据库专家

MySQL索引面试题精要总结 核心要点 B+树索引优势:非叶子节点只存索引键,叶子节点有序链表,减少IO次数,提高范围查询效率(3层B+树可支撑2000万数据)。 联合索引结构:按列顺序组合排序(如a,b,c),遵循最左前缀原则,否则无法利用索引。 索引覆盖优化:查询字段全在索引中可避免回表,显著提升性能(EXPLAIN显示"Using index")。 索引失效场景:包括函数操作、隐式类型转换、LIKE前缀模糊、OR条件、不满足最左前缀等7类情况。 索引下推(ICP):MySQL 5.

成大事的博客 969

2026华为OD面试手撕代码真题目录

一般面试的时候每一轮技术面都会出一到两个手撕代码题,这些题的特点就是,非常短小,易于理解。不可能会再出阅读理解一样的机试题的。但是这些题目也非常注意基本功,很注意细节的处理,一般都是easy+medium题目。但是大家一定要注意,因为大部分面试官上面一开始就会让你做题,直接看你所有的做题过程(防止有人水平一般,机试就网上找的答案的蒙混过关),手撕代码题会给你后面的面试定一个基调。

MISAYAONE的博客 9万+

SAP B1中文培訓教材_SDK

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

mysql索引b+树原理,MySQL系列

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典Java核心知识整理Java核心知识Spring全家桶(实战系列)其他电子书资料Step3:刷题既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。ep3:刷题**

1036

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Mysql数据库中b树和b+树的区别 - 面试宝典

在实际应用中,需要根据数据的特点和查询需求选择合适的索引结构。B树适用于随机读取和范围查询较多的场景,而B+树适用于范围查询较多的场景。需要注意的是,索引的创建和维护可能会增加写操作的开销,因此需要权衡索引的使用。同时,索引的选择也需要考虑到数据库的大小、查询频率等因素。MySQL数据库中,B树和B+树是常用的索引结构,用于提高数据检索的效率。它们在实现原理和适用场景上有一些区别。

牛肉胡辣汤 611

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

字节面试题: Mysql索引结构,为什么要用b+树?

在数据库管理系统中,索引是一种数据结构,用于快速定位和访问数据库表中的特定记录。它类似于书籍的目录,可以帮助数据库系统快速定位到数据所在的位置,而不必扫描整个数据表。MySQL支持多种类型的索引,包括主键索引、唯一索引、普通索引和全文索引等。

jakelihua 1285

广义表怎么画成树_MySQL详解之InnoDB:B+ 树索引、哈希索引、全文索引

MySQL复习:20道常见面试题(含答案)+21条MySQL性能调优经验春招指南之“性能调优”:MySQL+Tomcat+JVM,还怕面试官的轰炸?秋招Java面试大纲:Java+并发+spring+数据库+Redis+JVM+Netty等面试终败“高并发”,25天苦心钻研,居然整出一份并发宝典?在数据库中,如果索引太多,应用程序的性能可能会受到影响,如果索引太少,又会对查询性能产生影响。所以,我...

weixin_39628339的博客 1548

字节面试: Mysql为什么用B+树,不用跳表?

MySQL中的B+Tree 原理B+Tree一般由多个页、多层级组成,在MySQL中每个页 16 KB。主键索引的 B+ 树的叶子结点才是数据,非叶子结点(内节点)存放的是索引信息。上下层的页通过单指针相连。同一层级的相邻的数据页通过双指针相邻。B+Tree的结构B+Tree一个节点是一个page,是一种多叉树结构,每个结点都是一个16k的数据页,能存放较多索引信息。一次IO一个page,大大节省了磁盘IO的操作。B+Tree一个page 能存放较多索引信息 ,所以树的层数比较低,三层。

架构师尼恩 3847

Mysql学习宝典(三) -- Mysql索引原理以及应用解析并对数据结构进行推演

MySQL 索引原理详解 一、 索引是什么? 1.1. 索引是什么 S ​ 当一张表有 500 万条数据,在没有索引的 name 字段上执行一个查询: select * from user_innodb where name ='jim'; ​ 如果 name 字段上面有索引呢? ALTER TABLE user_innodb DROP INDEX idx_name; ALTER TABLE user_innodb ADD INDEX idx_name (name); ​ 索引的创建是需要消耗时

aaa31203的博客 4974

MySQL 索引、B+树原理以及建索引的几大原则

python 技术拓展 MySQL 索引、B+树原理以及建索引的几大原则 MYSQL一直了解得都不多,之前写sql准备提交生产环境之前的时候,老员工帮我检查了下sql,让修改了一下存储引擎,当时我使用的是Myisam,后面改成InnoDB了。为什么要改成这样,之前都没有听过存储引擎,于是网上查了一下。 事实上使用不同的存储引擎也是有很大区别的,下面猿友们可以了解一下。 一、存储引擎的比较 注:上面提到的B树索引并没有指出是B-Tree和B+Tree索引,但是B-树和B+树的定义是有区别的。 在 MySQL

bishe_teacher的博客 233

MySQL索引“B,阿里大佬亲授“Java性能调优技术宝典”

通常我们在建立联合索引的时候,也就是对多个字段建立索引,相信建立过索引的同学们会发现,无论是Oracle还是 MySQL 都会让我们选择索引的顺序,比如我们想在a,b,c三个字段上建立一个联合索引, 我们可以选择自己想要的优先级,a、b、c,或者是b、a、c 或者是c、a、b等顺序。其实这里说的有一点歧义,其实(a,c)也会走,但是只走a字段索引,不会走c字段。此时select的字段name,age在索引name_age_index中都能获取到,所以不需要回表,满足索引覆盖,直接返回索引中的数据,效率高。

2401_83620690的博客 448

面试宝典:MySQL中索引为什么使用B+树的深度分析

在高级数据库开发和优化的面试中,索引的结构和原理是一个绕不开的话题。MySQL中,B+树是最常见的索引结构,它在性能和效率上都具有显著的优势。本文将深入分析为什么MySQL的索引选择使用B+树,以及B+树的特性如何使其成为数据库索引的理想选择。

weixin_39801169的博客 642

【MySQL 数据宝典】【索引原理】- 003 用例子说明索引优化基础原则

最左前缀法则要遵守索引列上不计算范围之后全失效覆盖索引记住用。不等于、is null、is not null、or导致索引失效。like百分号加右边,加左边导致索引失效,解决方法:使用覆盖索引。

黄金时代的架构之路 820

【MySQL 数据宝典】【索引原理】- 005 一文说明白 OrderBy 优化

如果 MySQL 认为内存足够大,会优先选择全字段排序,把需要的字段都放到 sort_buffer中, 这样排序后就会直接从内存里面返回查询结果了,不用再回到原表去取数据。MySQL 的一个设计思想:如果内存够,就要多利用内存,尽量减少磁盘访问。对于 InnoDB 表来说,rowid 排序会要求回表多造成磁盘读,因此不会被优先选择。

黄金时代的架构之路 866
上一篇: ~/.bashrc、 ~/.bash_profile、~/.profile、 /etc/profile几个配置文件的区别
下一篇: MySQL 实战宝典(七):MySQL 连接查询、嵌套子查询与性能优化原理
TracyCoder123
博客等级 码龄8年 1万+粉丝 226原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TracyCoder123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值