【浅学Java】MySQL索引七连炮

0. 谈一下你对索引的理解

首先。MySQL里面存的一些索引,索引的数据结构是通过B+树或者哈希表生成的。

存储引擎:
对于不同类型的索引,是与存储引擎相关的,如果你使用的是Myisam或者Innodb这样的存储引擎,那对应的数据类型就是B+树;如多使用的Memory这种存储引擎,那所使用的数据结构就是哈希表。不同的存储引擎表示的是不同的数据在磁盘上的组织形式。

为什么InnoDB和Myisam要使用B+树呢?
首先,我们得清楚,索引里面存储得是什么。一般情况下,索引里面存储的是Key,通过key去找到对应的value。对于这种key-value形式的数据,我们可以采用的数据结构有很多选择,比如:哈希表、二叉树、AVL树、B+树。

不管使用什么形式的二叉树,它最终都会导致树高度的增高,这就会使io的次数增多,使得整体的io访问的效率降低。而不使用哈希表是因为它不支持范围查找。

选择B+树这样的数据结构之后,他就会尽多的在一个数据节点里面存储数据,让树的高度变低,从而减少io的次数,提高数据访问的效率。

索引分类:
在MySQL里面有主键索引、唯一性索引、普通索引、组合索引、全文索引等各种索引。在日常的开发中,最常用到的可能就是主键索引和组合索引,在使用这两种索引的时候,会存在一系列问题,比如:回表、覆盖索引、最左匹配、索引下推。

在执行SQL语句的时候,可以通过索引的一些点来进行优化,提高我们对于数据的访问效率。

1. MySQL索引原理和数据结构能介绍一下吗

MySQL的索引底层使用B+树来进行数据的存储。
使用B+树的优点:

  1. B+树是一个多叉搜索树,可以进行数据的查找操作
  2. B+树的非叶子节点只存储Key值,这样就可以在一个数据节点里面存储更多的数据,从而降低树的高度,减少IO访问的次数,从而提高数据查询的效率。
  3. B+树的叶子节点存储数据的详细信息,每个数据在叶子节点上都有体现,并且这些叶子节点用链表的形式连接起来,从而支持范围查找。

2. B+树和B树的区别

我们先来看看两种数据结构的数据存储模型图:
在这里插入图片描述
下面来总结一下两者的区别:

  1. B树的键值分布在整个树中;而B+只在叶子节点存储键值,非叶子节点只存储Key值
  2. B+树的叶子节点是以链表的形式进行存储,可以支持范围查询;而B树不行
  3. B+树的数据节点中只存储Key,而B树的数据节点中还存储data,这就意味着B+树单次磁盘 IO 的信息量大于B树,从这点来看B+树相对B-树磁盘 IO 次数少

3. MySQL聚簇索引和非聚簇索引的区别

想要理解聚簇索引和非聚簇索引的区别,那我们先来理解一下下面的这些东西:

对于InnoDB存储引擎,在插入数据的时候,数据必须和索引绑定到一起,索引可以是主键,可以是唯一性键,也可以是6字节的rowid。

在一个表中,可能有多个索引,但是数据只能有一份,不会造成文件的冗余。当数据跟某一个索引列绑定到一起的时候,其他的索引列应该如何检索数据呢?

方法是:将 已经跟数据绑定的索引列的值 放到其他索引的叶子节点。

id为主键时,用主键建立的索引结构:
在这里插入图片描述

而id为主键时,以name建立的索引:
在这里插入图片描述

  1. InnoDB是通过B+树结构对主键创建索引,然后叶子节点存储记录,如果没有主键,就用唯一性键创建索引,如果没有唯一性键,就用6字节的row_id来作为主键创建索引。
  2. 如果创建索引的键是其他字段,那么在叶子节点存储的就是该记录的主键,然后再通过主键索引来找到对应的记录,这就做回表

理解了上面这些,再来谈谈聚簇索引和非聚簇索引:

聚簇索引:索引跟数据放到一起,比如上面的 id
非聚簇索引:索引跟数据没有直接放到一起,需要通过回表才能查询到数据,比如上面的name

还有一个小知识:

  1. 在InnoDB存储引擎当中,既存在聚簇索引,也存在非聚簇索引。
  2. 在myisam存储引擎当中,只存在非聚簇索引,根本原因是:myisam存储引擎索引列单独是一个文件

4. 使用MySQL索引都有什么原则

4.1 回表

从某一个索引的叶子节点拿到聚簇索引的id值,然后再根据id值去聚簇索引里面找到对应的全量信息。设计回表查询的效率不高,一次回表使io次数翻倍,要尽量减少回表。

假设有一个表:id,name,age,gender四个列,id为主键,name为普通索引

当执行 select * from table where name = "zhangsan"时,它得先在name索引中找到主键id的值,然后再去id索引中查询全列信息。

4.2 索引覆盖

从索引的叶子节点中,能获取全量查询列的过程就叫做覆盖索引,覆盖索引不需要再回表。

假设有一个表:id,name,age,gender四个列,id为主键,name为普通索引

当执行 select id,name from table where name = "zhangsan"时,再name索引中,可以查到id,也可以查到name,此时就不需要再进行回表。

4.3 最左匹配

对于组合索引,要遵循最左匹配原则,即:索引的匹配顺序必须是从左向右。

假设有一个表:id,name,age,gender四个列,id为主键,name和age为组合索引

当执行如下语句的时候,那些能用到组合索引?

select * from table where name="zhangsan" and age=10;
select * from table where name="zhangsan";
select * from table where age=10;
select * from table where age=10 and name="zhangsan";

答案是:1,2,4可以使用组合索引。原因如下:

第1个是标准的顺序,没问题
第2个是查询name,符合最左匹配,也没问题
第3个把name跳过了,不符合组合索引的要求
第4个是mysql索引优化器对索引的顺序进行了调整,因为age和name的顺序对查询结果没有影响。

4.4 索引下推

MySQL的组成部门:
在这里插入图片描述

当执行 select * from table where name=“zhangsan” and age=10 时

  1. 在没有索引下推之前:先根据name去存储引擎拿到全量的数据,在将数据读取到server层,然后server层再根据age进行筛选,将最终结果返回给客户端
  2. 有了索引下推之后:直接根据name和age去存储引擎拿到全量数据,然后将最终结果返回给客户端

5. 不同的存储引擎是如何进行数据的存储的

在InnoDB中:
在这里插入图片描述

frm存储表结构相关的东西
ibd存储的是实际的数据

在Myisam中:
在这里插入图片描述

frm存储表结构相关东西
MYD存储数据
MYI存储索引

两者数据的存储的区别:在InnoDB中,数据和索引存储在一起,而在myisam当中,数据和索引分开存储,这也便是myisqm只有非聚簇索引的原因。

6. MySQL组合索引的结构是怎样的

和普通索引就一个区别:key值多为多个,即(key,key)——>value.

7. MySQL索引是如何进行优化的

待沉淀。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值