MySQL中的“表返回”是什么?
1。索引结构
要理解这个问题,首先要了解MySQL中索引存储的数据结构。其实很多朋友可能都听说过这个,B+Tree!
什么是B+3?那你首先得明白什么是B-Tree。看一下下面这张图:
前面是B-Tree,后面是B+Tree。两者的区别在于:
- 在B-Tree中,所有节点都带有指向特定记录的指针;只有 B+Tree 中的叶节点才会有指向特定记录的指针。
- B-Tree 中不同的叶子不相连; B+Tree中的所有叶子节点都通过指针连接。
- 在B-Tree中,可以从没有叶子的节点中获取指向特定记录的指针,搜索效率不稳定;在B+Tree中,必须从叶子节点获取指向特定记录的指针,搜索效率不稳定。稳定。
基于以上两点分析,我们可以得出以下结论:
- 在B+Tree中,由于非叶子节点没有指向具体记录的指针,因此非叶子节点元素中可以存储更多的索引,可以有效降低树的高度,从而提高搜索效率。
- 在B+Tree中,叶子节点是通过指针连接的,所以如果需要范围扫描的话,会非常容易实现。然而,对于B-Tree来说,范围扫描需要不断扫描叶子节点并在非叶子节点之间移动。
第一点,一个B+Tre可以存储多少数据?如果以主键索引的B+Tree为例(二级索引存储的数据量计算原理是一样的,只是叶子节点和非叶子节点存储的数据格式略有不同) ,我们可以做一个简单的计算。
计算机存储数据时,最小的存储单位是扇区,一个扇区的大小为512字节。文件系统(如XFS/EXT4)中的最小单位是块,块的大小为4KB。 InnoDB引擎存储数据时,是基于页的。每个数据页的默认大小为16KB,即四个块。
根据这个知识储备,我们可以大致算出一个B+Tre可以存储多少数据。
假设数据库中一条记录为1KB,一页可以存储16条数据(叶子节点);对于非叶子节点,存储的是主键值+指针。在InnoDB中,指针的大小为6字节。假设我们的主键是bigint,那么主键占用8个字节。 当然还有其他头信息也会占用字节。这里就不考虑了。我们来粗略算一下。小伙伴们,你可能有一个想法:
16*1024/(8+6)=1170
即一个没有叶子的节点可以指向1170个页面,那么一个三层B+的数据量是多少?树可以存储即:
1170*1170*16=21902400
可以存储2100万位数据。
在InnoDB存储引擎中,B+Tree的高度一般为2-4层,可以满足千万级数据的存储需求。在查找数据时,一次分页查找就代表一次IO,那么我们使用主键进行索引查询时,实际最多需要2-4次IO操作。
大家首先要了解这个B+Tree。
2。索引的两类
众所周知,MySQL中的索引有很多种不同的分类方法。它们可以根据数据结构、逻辑角度或物理存储进行分类。其中,按照物理存储方式可以分为聚集索引和非聚集索引。
我们日常所说的主键索引,其实就是聚集索引;除主键索引外,其他都称为非主键索引,非主键索引也称为辅助键索引。 ,或称为辅助索引。
对于主键索引和非主键索引,使用的数据结构都是B+Three。唯一的区别是叶子节点存储的内容不同:
- 主键索引的叶子节点存储的是完整的一行数据。
- 非主键索引的叶子节点存储主键值。
这是两者最大的区别。
所以,当我们需要查询时:
- 如果通过主键索引来查询数据,例如
select * from user where id=100
,那么只需要主键的索引B需要进行搜索。 +树来查找数据。 - 如果通过非主键索引查询数据,例如
select * from user where username='javaboy'
,首先要在username列索引中查找B+Tree。查找完成后,就会得到主键的Value,然后在主键索引的B+Tree中查找,就可以得到一行完整的数据。
对于第二种查询方式,一共检索了两个B+Tre。 第一次查找B+Tree,拿到主键值后,再查找主键索引的B+Tree。这个过程就是所谓的回表。
从上面的分析中我们也可以看出,通过非主键索引查询需要扫描两棵B+Tree,而通过主键索引查询只需要扫描一棵B+Tree,所以如果条件允许,建议以查询方式优先搜索主键索引。
3。表格会安全退回吗?
所以如果不使用主键索引,肯定要返回表?
不一定!
如果请求的列本身存在于索引中,则无需返回表,即使使用二级索引。
例如,我有下表:
unname 和 address 字段形成复合索引。此时,虽然这是一个二级索引,但是除了主键之外还存储了地址的值,索引树的叶子节点存储了该值。
我们看下面的分析:
可以看到此时使用了uname索引,但是最终额外的值是使用索引
,表示索引覆盖扫描(index)使用 ) ,此时直接从索引中过滤掉不需要的记录,并返回命中结果。这一步是在MySQL服务器层完成的,不需要回表。
4。扩展
根据第一部分和第二部分的分析,我们来看看为什么数据库中推荐使用自增主键。
- 自增主键往往占用空间较小,int占用4字节,bigint占用8字节。由于二级索引的叶子节点存储的是主键,如果主键占用的空间较小,则意味着以后二级索引的叶子节点占用的空间也会变小(间接降低B+Tree的高度)并提高搜索效率)。
- 自动递增主键插入速度更快。可以直接插入,不涉及叶子节点分裂等问题(不需要移动其他记录);而其他不自增的主键必须设置为2。在现有的数据中心中,它可能会导致以下问题:叶子节点共享,插入效率低(必须移动其他记录)。
当然,这是基于技术层面的讨论。如果业务无法使用主键自动增加或者有其他需求阻止使用主键自动增加,那就没有其他办法了。当您满足新要求时,只需选择最佳实践即可。 。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。