Mysql 索引(一)—— 主键索引的底层原理

文章详细阐述了MySQL中索引的作用,如何通过Page结构和B+树优化磁盘交互,减少IO次数,提高查询效率。在主键索引机制部分,介绍了从顶层目录到数据页的查找过程,以及在增删查改操作中的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引的作用是提升Mysql的检索速度

  • 如果没有索引:若我们要在几百万条记录中找出一个名为“张三”的人,这个时候我们只能逐条遍历记录,直至找到这个人;
  • 如果有索引:假设名为“张三”的人所在记录的索引为 999,我们只需要像在目录中查页码一样,很快就可以知道第 999 页大概在哪一个章节。

索引虽然是以插入、更新、删除的速度为代价的,这些写操作增加了大量的IO,但是这些代价带来的就是海量数据的检索速度的提升。


         目录

1、Mysql 和 磁盘交互的基本单位

2、深入理解一个page

3、理解多个page

3、Mysql 主键索引机制

(1) 整体架构

(2) 增删查改的过程


1、Mysql 和 磁盘交互的基本单位

假设 Mysql 查询一条记录的时候,不可能仅仅加载一条记录到内存,如果要频繁查询,就会增加和磁盘的IO次数,这样既费时又费力。

为了减少和磁盘IO的次数,Mysql 每次查询会加载 16 KB 到内存,所以 Mysql 和磁盘交互的基本单元是 16 KB。站在Mysql的角度,一个基本单元就是一个 page,每个page中都保存了多条记录,而 Mysql 的一个表格可以由多个page链接而成。

2、深入理解一个page

一个page中保存了多条记录,但是在检索的时候,每进入一个page查询,依然需要逐个遍历,这样看来,检索效率并没有提升多少。

实际上,为了提升单个page的检索效率,每个page除了保存数据库记录外,还会有对应的索引目录。(类似于书本的目录),这样的话我们在查找的时候,其实是根据目录来查询,这样可以减少检索次数,提升检索效率。

假设我们要查询索引为 4 的记录,此时Mysql在查询第一个page中的目录时,

  • 查询目录1:指向的是索引为1的记录,下一条指向的是索引为3 的记录,要查找的内容不在此范围,直接跳过
  • 查询目录2:指向的是索引为3的记录,下一条指向的是索引为5的记录,要查找的内容在这个范围内,于是进入该目录指向的范围逐个遍历。

3、理解多个page

假设现在有 1000 个page,我们要找某一条记录,最坏的情况下我们要遍历1000个page,我们沿用上面单个page的思路,每100个page做一个目录页,目录中每一条保存的是所指向的page页的最小索引值

假设我们要查询索引值为4的记录:

  • 在第一层目录中查找:第一条符合,第二条不符合,所以索引值为4的记录在第一条记录指向的page中
  • 在第二层目录中查找:可以参考上述单个page的检索过程

3、Mysql 主键索引机制

(1) 整体架构

目录页的本质也是页,最底层的页存的是用户数据,而目录页中存的是下一层page的地址。实际上,如果目录页比较多,依然可以采用同样的思路,继续增加一层目录页。最终可以了解到Mysql索引机制使用的数据结构就是 B+ 树。

(2) 增删查改的过程

每次检索的时候,一层一层向下查找,到了最后一层再进入到page页中遍历记录。找到以后,再把记录所在的page一起加载到内存中。(这也就解释了为什么Mysql和磁盘交互的基本单位是一个page

每次插入或者删除的时候,都是先在内存中操作对应的page页,更新时直接替换原本的page。

无需每一条都去遍历,只需要自上而下,按层遍历,也不需要加载太多无效数据,每次加载数据都会获取到我们需要的数据

### MySQL 中非主键索引的 B+Tree 实现原理底层结构 在 MySQL 的存储引擎中,无论是 MyISAM 还是 InnoDB,都广泛采用了 B+Tree 数据结构作为索引的核心实现方式[^2]。下面详细介绍非主键索引(Secondary Index)基于 B+Tree 的实现及其底层逻辑。 #### 1. 非主键索引的特点 非主键索引也被称为辅助索引或次级索引,在 InnoDB 存储引擎下,它与主键索引有显著区别。由于 InnoDB 使用的是聚簇索引(Clustered Index),表中的数据按照主键顺序物理存储,而非主键索引则通过指向主键的方式间接访问实际记录[^3]。 - **叶子节点的内容** 对于非主键索引来说,其叶子节点不仅包含索引列的值,还额外保存了对应主键的值。这种设计使得当查询命中非主键索引时,能够快速定位到对应的主键位置并进步获取完整的行数据[^4]。 #### 2. B+Tree 的基本特性 B+Tree 是种多路平衡查找树,具有如下特点: - 所有的关键字均存放在叶子节点上; - 非叶子节点仅用于引导搜索方向,不存储真实的数据项; - 叶子节点之间存在链表连接,便于范围扫描操作; 这些特征决定了 B+Tree 特别适合数据库系统的应用场景——频繁地进行随机读写和大范围检索操作[^5]。 #### 3. InnoDB 下非主键索引的工作机制 假设有个名为 `users` 的表格,定义了个整数类型的字段 `age` 并为其创建了非主键索引,则该索引的实际布局大致如下: ```plaintext | age | primary_key | --------------------- | 20 | 10 | | 25 | 15 | | 30 | 20 | ... ``` 这里每条记录由两部分组成:索引列本身 (`age`) ,二是关联的主键(`primary_key`)旦用户发起针对年龄字段的查询请求 (e.g., SELECT * FROM users WHERE age=25),系统会先利用上述索引来找到匹配条件的第笔资料的位置,接着再依据所得到的那个主键主键索引里做第二次查找以取出最终的结果集。 此过程通常被描述为“回表”,即除了第次使用非主键索引外还需要再次回到主键索引完成整个取数流程。如果能减少甚至避免这种情况的发生(比如只选取那些已经存在于非主键索引里的信息), 就可以有效提升性能表现. #### 4. 性能考量 为了优化涉及非主键索引的操作效率, 开发者应当注意以下几点建议: - 如果可能的话尽量覆盖查询(Covering Query): 让所有需要用到的信息都能直接从某个单索引内部获得而无需多次跳转. - 合理设置复合索引: 当多个过滤条件经常起出现的时候考虑建立联合索引可能会带来更好的效果. --- ### 示例代码展示如何查看当前库内的索引情况 以下是几个常用的 SQL 命令可以帮助开发者理解现有表上的各种索引配置: ```sql -- 查看某张表的所有索引详情 SHOW INDEX FROM table_name; -- 获取更详细的元数据统计关于特定索引 SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME='table_name'; ``` 以上命令适用于大多数标准版 MySQL 安装环境之中. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值