mysql数据库存储引擎和索引的描述_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存储引擎中,数据和索引的关系如下:

ade17fba0dfed56d7f194e3ee3cdb564.png

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

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

64762e7c89c6fb35f1c70995e95ed2e1.png

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

Innodb存储引擎:

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

.frm 表的定义文件

.ibd 索引文件

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

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

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

6d84d05c6a5bbe32b737da133170a905.png

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

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

02cbbd640cdd5d61dd49df577d15b3a2.png

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

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

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

4d54a0d85318531f2096626db9809f38.png

创建索引的几大原则:

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 *,要写明具体要查询的字段,一个原因就是,这样在使用到覆盖索引的情况下,不需要进入到数据区,数据就能直接返回,提升了查询效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值