记,在公司内部做的关于MySQL索引的分享

本文详细介绍了数据库索引(包括普通索引、组合索引、回表查询、索引覆盖和最左前缀原则)在MySQL中的应用,以及索引下推和全文索引的概念。同时提到了Java开发者面试中可能遇到的问题,强调了优化查询性能对开发实践的重要性。
摘要由CSDN通过智能技术生成

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

普通索引

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

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

// 创建表的时候创建

CREATE TABLE user(

id INT PRIMARY KEY NOT NULL,

name VARCHAR(16) NOT NULL,

INDEX index_name (name(10))

);

// 创建表后创建

CREATE INDEX INDEX index_name ON user(name(10));

// 修改表结构创建

ALTER user ADD INDEX index_name ON (name(10))

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

DROP INDEX index_name ON user;

组合索引

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

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

// 其它方式和上面的一样,这里就只列举修改表结构的方式创建

ALTER TABLE employee ADD INDEX name_age_sex (name(10),age,sex);

回表查询

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

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

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

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

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

在公司内部做的关于MySQL索引的分享,总监说我是专家级的…

主键索引树

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

在公司内部做的关于MySQL索引的分享,总监说我是专家级的…

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

在公司内部做的关于MySQL索引的分享,总监说我是专家级的…

回表原理图

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

索引覆盖

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

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

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

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

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

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

最左前缀原则

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

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

nameagesexad23男bc21男bc24女bc25男de21女

如上图所示,对于联合索引中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%’;就可以使用索引,因为最左边的字符串是确定的,这种称为**「匹配列前缀」**。

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

索引下推

Mysql5.6版本提出了索引下推的原则,「用于查询优化,主要是用于like关键字的查询的优化」,什么是索引下推呢?

下面通过演示来说明一下它的概念,还是利用原来的employee测试表,假如我要执行下面的sql进行查询:SELECT * from user where name like ‘张%’ and age=40;

假如没有索引下推,执行的过程如下图所示:

在公司内部做的关于MySQL索引的分享,总监说我是专家级的…

查询会直接忽略age字段,将name查询的张开头的id=5、id=7的结果返回给Mysql服务器,再执行两次的回表查询。

若是上面的查询操作使用了索引下推,执行的过程如下:

在公司内部做的关于MySQL索引的分享,总监说我是专家级的…

Mysql会将查询条件age=40的查询条件传递给存储引擎,再次过滤掉age=50的数据行,这样回表的次数就变为了一次,提高了查询效率。

总结起来索引下推就是在执行sql查询的时候,会将一部分的索引列的判断条件传递给存储引擎,由存储引擎通过判断是否符合条件,只有符合条件的数据才会返回给Mysql服务器。

全文索引


全文索引也称为全文检索,可以通过以下sql建立全文索引:ALTER TABLE employee ADD FULLTEXT fulltext_name(name);或者CREATE INDEX的方式创建。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

总结

以上是字节二面的一些问题,面完之后其实挺后悔的,没有提前把各个知识点都复习到位。现在重新好好复习手上的面试大全资料(含JAVA、MySQL、算法、Redis、JVM、架构、中间件、RabbitMQ、设计模式、Spring等),现在起闭关修炼半个月,争取早日上岸!!!

下面给大家分享下我的面试大全资料

  • 第一份是我的后端JAVA面试大全

image.png

后端JAVA面试大全

  • 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

大全资料**

  • 第一份是我的后端JAVA面试大全

[外链图片转存中…(img-0il689Xw-1710433484493)]

后端JAVA面试大全

  • 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理

[外链图片转存中…(img-iVSO4eB8-1710433484494)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

[外链图片转存中…(img-6xprzZDQ-1710433484494)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值