Mysql使用的B+树和存储引擎的关系

Posted 王小花flower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql使用的B+树和存储引擎的关系相关的知识,希望对你有一定的参考价值。

这个知识点的参考文章是:原文链接:https://blog.csdn.net/b_x_p/article/details/86434387

 

mysql是使用B+树作为索引的数据结构,Mysql有两种不同的数据存储引擎:MYISAM 和 INNODB,在Mysql5.5版本之前采用的是MYISAM,5.5之后采用的是INNODB

首先看看mysql是怎么保存数据的

在/var/lib/mysql这个目录下保存的是所有的数据库

使用MYISAM存储引擎的数据库有三个文件:

.frm 表的定义文件

.MYD 数据文件,所有的数据保存在这个文件中

.MYI 索引文件

在MYISAM存储引擎中,数据和索引的关系如下:

 

 

 

如果要查询id=101的数据,先根据MYI索引文件去找id=101的节点,通过这个节点的数据区拿到真正保存数据的磁盘地址,再通过这个地址从MYD数据文件中加载对应的记录

如果有多个索引,表现如下:

 

 

所以在MYISAM存储引擎中,主键索引和辅助索引是同级别的,没有主次之分。

Innodb存储引擎:

Innodb以主键索引来聚集和组织数据的存储,看下Innodb的数据库文件:

.frm 表的定义文件

.ibd 索引文件

没有专门的数据文件,数据都是在叶子节点中,innodb设计的初衷也是也为主键才是最主要的索引

首先看一下聚集索引的概念:数据表中行的数据的物理顺序和键值的逻辑顺序相同

 

在Innodb中,索引文件是这样的:

 

 叶子节点的数据区保存的是真实的数据,再通过索引进行检索的时候,命中叶子节点,就可以直接从叶子节点中取出行数据

那么在Innodb中,辅助索引和主键索引是怎么表现形式呢?

 

 

 因为主键索引的叶子节点保存的是真正的数据,辅助索引的叶子节点的数据区保存的是主键索引关键字的值,所以如果按照辅助索引的字段去查询数据,执行的过程是

现在辅助索引中查询到主键id=101,再到主键索引中搜索id=101的数据,最终在主键索引的叶子节点中获取真正的数据,通过辅助索引进行检索,需要检索两次索引

两个不同的存储引擎查找数据的过程:

 

 

创建索引的几大原则:

1、列的离散型:
离散型的计算公式:count(distinct col):count(col),离散型越高,选择型越好。

2、最左匹配原则:

对索引中的关键字对比的时候,一定是从左往右对比的,不能跳过,当我们的索引字段是字符串的时候,是转换为ascii码,然后从左往右一个字符一个字符对比的,如果在sql查询中,使用like %开头,代表全匹配,全匹配就表示不需要走索引

3、最少空间原则

当关键字占用的空间越小,那么每个节点保存的关键字个数就越多,这样每次加载到内存的关键字个数越多,检索效率就会越高

联合索引:

单列索引:节点中的关键字是单列的,如[name]

联合索引:节点中的关键字是多列的,如[name,phoneNum]

单列索引是一种特殊的联合索引,联合索引也是根据最左匹配原则

联合索引的列的选择的原则是:

经常使用的列优先,最左匹配原则

离散度高的列优先,离散度高原则

宽度小的列优先,最少空间原则

冗余的索引会增加B+树平衡时的性能消耗,并且占用磁盘空间

 

覆盖索引:

如果查询的列,通过索引项的信息可直接返回,这样的索引就称之为查询sql的覆盖索引,覆盖索引可以提高查询效率,避免了一次回表查询

下面通过例子说明覆盖索引。
表:teacher
索引:PK(id), key(name, phoneNum), unique(teacherNo)

下面哪些sql使用到了覆盖索引?

Select teacherNo from teacher where teacherNo = ?:使用到了,检索到teacherNo 时候,可以直接将索引中的teacherNo 值返回,不需要进入数据区。

Select id,teacherNo from teacher where teacherNo = ?:使用到了,辅助索引的叶子节点保存了主索引的值,所以检索到辅助索引的叶子节点的时候就可以之间返回id。

Select name,phoneNum from teacher where teacherNo = ?:没有用到

Select phoneNum from teacher where name = ?, 使用到了。

知道了覆盖索引,就知道了为什么sql中要求尽量不要使用select *,要写明具体要查询的字段,一个原因就是,这样在使用到覆盖索引的情况下,不需要进入到数据区,数据就能直接返回,提升了查询效率。

 

以上是关于Mysql使用的B+树和存储引擎的关系的主要内容,如果未能解决你的问题,请参考以下文章

MySQL InnoDB存储引擎选择B+树作为索引数据结构的原因

B+树|MYSQL索引使用原则

MySQL 使用B+树

Mysql知识点整理

为什么用B+树做索引&MySQL存储引擎简介

B+树和B树的区别? 为什么MYSQL要用B+ 树而不用B树