2024年最新想进大厂,这些Mysql索引底层知识你是必须知道的,Java面试官最爱问的垃圾回收机制

最后

本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们

目录:

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

Java面试核心知识点

一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

Java面试核心知识点

已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

这一篇是讲解Mysql中做使用到的「索引的种类」,「索引正确使用的原则」、「怎么优化索引」、「以及两种存储引擎InnoDB和MyISAM索引的数据布局原理」。

索引种类

在说索引之前,我们先来说一说什么是索引呢?对于索引个人的理解就是,索引是一种加快查询数据的数据结构。

所以,索引就是一种数据结构,作用就是发挥这种数据结构的作用,加快查询的效率,例如:InnoDB存储引擎中使用的是就是B+tree这种数据结构来组织索引。

Mysql中索引的种类也不是很多,不同类型的索引有不同的作用,索引的作用相互之间也存在交叉关系,Mysql中索引主要分为以下几类:

  1. 「主键索引」(PRIMARY KEY):主键索引一般都是在创建表的时候指定,「一个表只有一个主键索引」,特点是「唯一、非空」。

  2. 「唯一索引」(UNIQUE):唯一索引具有的特点就是唯一性,可以在创建表的时候指定,也可以在创建表后创建。

  3. 「普通索引」(INDEX):普通索引唯一的作用就是加快查询。

  4. 「组合索引」( INDEX):组合索引是创建一个「多个字段的索引」,这个概念是相对于上上面的单列索引而言,组合索引查询遵循「最左前缀原则」。

  5. 「全文索引」(FULLTEXT):全文索引是针对一些大的「文本字段」创建的索引,也称为「全文检索」。

  6. 「聚簇索引」和「非聚簇索引」:聚簇索引和非聚簇索引的概念比上面的概念要大,属于包含和被包含的关系。例如:InnoDB中主键索引使用的就是聚簇索引。

若是你想查看一个表的所有索引,可以执行下面的sql来查看:

show index from 表名

例如,查看我自己的测试表里面的索引,如下图所示,Key_name表示索引的名字,Column_name表示索引的字段。

上面大概的说了主要索引的概念,下面详细的介绍一下这几大索引的特点和使用。

主键索引

主键索引在InnoDB存储引擎中是最常见的索引类型,一个表都会有一个主键索引,它索引的字段不允许为空值,并且唯一。

一般是在创建表的时候,可以通过RIMARY KEY指定主键索引,在InnoDB存储引擎中,若是创建表的时候没有主观创建主键索引,Mysql就会看表中是否有唯一索引,有,就会指定「非空的唯一索引」为主键索引;

没有,就会默认生成一个6byte空间的自动增长主键作为主键索引,可以通过select _rowid from 表名查询的是对应的主键值.。

MyISAM储存引擎是可以不存在主键索引,MyISAM和InnoDB储存数据的结构方式还是有明显的区别,这个后面篇章会详细讲解。

唯一索引

唯一索引与主键索引的区别就是,唯一索引允许为空,若是在组合索引中,只要创建的列值是唯一的

唯一索引在实际中更多的是用来保证数据的唯一性,假如你仅仅要数据能够快速查询,你也可以使用普通索引,所以唯一索引重在体现它的唯一性。

实际的业务场景,有些库表字段要求唯一,就可以使用唯一索引,创建唯一索引的方式有三种。

(1)一个是在创建表的时候指定,如下sql:

(2)也可以在表创建后创建,如下sql:

(3)通过修改表结构创建,如下sql:

这里有一个细节要注意的是创建的name字段,指定的长度是16字符,而创建的索引的长度制定的是10字符,因为也没有人的名字长度会超过10个字符,所以减少索引长度,能够减少索引所占的空间的大小。

普通索引

普通索引的唯一作用就是加快数据的查询,一般对查询语句WHERE和ORDER BY后面的字段创建普通索引。

创建普通索引的方式也有三种,基本和创建唯一索引的方式一样,只是把关键字UNIQUE换成INDEX,如下所示:

若是想删除索引,可以通过执行下面的sql进行删除索引:


组合索引

组合索引即用多个字段创建一个索引,组合索引能够避免「回表查询」,相对于多字段的单列索引,组合索引的查询效率更高。

创建组合索引(联合索引)的方式和上面创建普通索引的方式一样,只不过字段的数目多了,如下sql创建:

回表查询

什么是回表查询呢?回表查询简单来说「通过二级索引查询数据,得不到完整的数据行,需要再次查询主键索引来获得数据行」。

InnoDB存储引擎中,索引分为 「聚簇索引」和「二级索引」,主键索引就是聚簇索引,其它的索引为二级索引。

聚簇索引中的叶子节点保存着完整的数据行,而二级索引的叶子节点并不是保存完整的数据行。

上面提到InnoDB表是一定要有主键索引的,虽然索引占据空间,但是索引符合二分查找的算法,查找数据非常的快。

假设还是上面的employee表,里面有主键索引id,和普通的索引name,那么在InnoDB中就会存在两棵B+Tree,一棵是主键索引树:

在主键索引树中的叶子节点存储的是完整的数据行,另外一棵是name字段的二级索引树,如下图所示:

倘若你执行这条sql:select name, age, sex from employee where id =‘as’;就会先执行二级索引的查询,当查询name='as’时,得到主键为50,再根据主键查询主键索引树,得到完整的数据行,具体的执行流程如下:

这个就是回表查询,回表查询会查询两次,这样就会降低查询的效率,为了避免回表查询,只查询一次就能得到完整的数据呢?

索引覆盖

常见的方式就是「建立组合索引(联合索引)「进行」索引覆盖」,什么是索引覆盖呢?索引覆盖就是「索引的叶子节点已经包含了查询的数据,没必要再回表进行查询。」

假如我还是执行如下sql:select name, age, sex from employee where id =‘as’;因为普通索引只有name字段才建立了索引,这必然会导致回表查询。

为了提高查询效率,就(name)「单列索引升级为联合索引」(name, age, sex)就不同了。

因为建立的联合索引,在二级节点的叶子阶段就会同时存在name, age, sex三个的值,一次性就会获得所需要的数据,这样就避免了回表,但是所有的方案都不是完美的。

若是这个联合索引哪一天某一个数据行的name值改变了或者age改变了,我就需要同时维护主键索引和联合索引两棵树,这样的维护成本就高了,性能开销也大了。

相比之前数据的改变,我只需要维护主键索引即可,联合索引的创建就导致了需要同时维护两棵树,这样就会影响插入、更新数据的操作,所以并没有哪种方案是完美的。

最左前缀原则

我们知道单列索引是按照索引列有序性的进行组织B+Tree结构的,联合索引又是怎么组织B+Tree呢?

联合索引其实也是按照创建索引的时候,最左边的进行最开始的排序,也就是「最左前缀原则」,比如一个表中有如下数据:

name age sex ad 23 男 bc 21 男 bc 24 女 bc 25 男 de 21 女

如上图所示,对于联合索引中name字段是放在最前面的,所以name是完全有序的,但是age字段就不是有序的,只有当name相同,例如:name='bc’此时age字段的索引排序才是完全有序的。

所以你会发现,在联合索引中你只有使用以下的规则的方式查询才会使用到索引:

  1. name,age,sex

  2. name,age

  3. name

因为Mysql的底层有查询优化器,会判断sql执行的时候若是使用全表扫描的效率比使用索引的效率更高,就会使用全表扫描。

假如,我查询的时候使用age>=23,sex=‘男’;两个字段作为查询条件,但是没有使用name字段,因为在name不知情的条件下,对于age是无序的。

对于age>=23条件可能在很多的name不同中都有符合条件的出现,所以就没有办法使用索引,这也是索引实现的原因,一定要遵循「查找有序,充分的利用索引的有序性」。

假如你是分别在name,age,sex三个字段中分别建立三个单列索引,就相当于建立三颗索引树,那么它的查询效率,比我们使用一棵索引树查询效率就可想而知了。

有一种情况即使使用到了最左边的name字段也不会使用索引,例如:WHERE name like ‘%d%’;这种like条件的模糊查询是会使索引失效。

我们可以这样理解,「查询字符串也是遵循最左前缀原则的」,字符串的查询是对字符串里面的字符一个一个的匹配,「若是字符串最左边为%表示一个不确定的字符串,那么是没办法利用到索引的有序性」。

但是若是修改为 :WHERE name like ‘d%’;就可以使用索引,因为最左边的字符串是确定的,这种称为「匹配列前缀」。

实际业务场景中联合索引的创建,「我们应该把识别度比较高的字段放在前面,提高索引的命中率,充分的利用索引」。

索引下推

Ending

Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下

如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值