Mysql(5) - 索引优化与查询优化

本文介绍了数据库性能优化的几个关键方面:1) 对比了SNLJ, INLJ, BNLJ三种JOIN查询方式及其效率;2) 分析了子查询的效率问题及如何通过JOIN优化;3) 讨论了排序优化,特别是Order by索引的重要性;4) 解释了索引覆盖的概念及其优缺点;5) 详细阐述了索引下推(ICP)如何减少回表操作;6) 提倡使用明确的字段选择而非`SELECT *`以提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 , 关联查询优化

Join语句的三种执行方式:SNLJ,INLJ,BNLJ

我们用这条sql举例,假设t1中有n条记录,t2中有m条记录

SNLJ(Simple - Nest - Loop - Join)

最朴素的Join查询方式,执行流程就是:从t1中取出一条数据,拿这条数据的a字段与t2中比较,找到目标行返回,重复此操作。 这样的时间复杂度是最高的,O(N * M)。

INLJ(Index - Nest - Loop - Join)

先看图

可以看到,我们加入了索引,也就是优化了拿t1的数据去匹配t2的操作,在SNLJ中我们需要一条一条的匹配,但是加入了索引之后,这个查询操作的时间复杂度就大大降低了,O(n * logm)。但是增加了一个回表操作

 BNLJ - (Block - Nest - Loop - Join)

在SNLJ中我们是一条一条数据从t1拿出来,现在是一整块数据拿出来,那么自然匹配速度就快了,但是要更多的内存空间

二,子查询优化

        子查询可以帮助用更短的sql解决更复杂的问题,但是它的执行效率不高,原因主要有三个:

1.执行子查询时,mysql需要为内层查询的查询结果建立一个临时表,然后外层查询再从临时表中找到自己需要的记录。查询完毕后要撤销临时表。这对系统资源来说无疑是压力山大。

2.子查询中产生的临时表没有索引,索引查询起来性能很差

3.对于数据量很大的子查询,效率会更低

我们可以通过Join来连接查询以此替代子查询

 

三,排序优化

我们已经对where条件字段创建了索引,为什么还要对Order by也创建索引呢?

1.在数据量大的情况下我们要尽量避免系统排序(file sort),节省系统资源

2.在无法使用索引的情况下,我们需要对file sort进行优化

filesort的两种排序方式:

单路排序:把需要排序的字段和查询的字段全部拿出来放在sort buffer中进行排序(前提是sort buffer够大)

双路排序:仅将需要排序的字段和可以反映行具体位置的字段取出到sort buffer进行排序,再根据排序的结果回到原表中取数据,这个过程要经历两次的IO操作

所以总体来说单路排序效率要高于双路排序,但是对sort buffer的大小有要求,我们需要尽可能保证其容量足以满足单路排序

四,索引覆盖

什么是索引覆盖?

简单理解就是索引包含了我们查询的所有字段。比如你创建了一个index(a,b,c),而你要查询的字段是a,b,那么此时通过该索引找到的数据就是你所需要的数据,不需要再进行回表操作

索引覆盖的优点:

1.减少了磁盘IO次数

2.将随机IO变为顺序IO

缺点:

索引的维护是需要成本的

五:索引下推(Index Condition Push down)简称ICP

在该sql语句的场景下,假如没有索引下推,那么我们会先根据索引找到符合zipcode找到符合条件的所有行,并且一行一行的回表,去主键索引判断是否符合后面的like条件。  但是有索引下推回怎么样呢? 它会在根据索引找到所有符合条件的数据后,根据后面的like条件(只能是lastname,因为我们的索引没有包含address)进行一次筛选,留下满足后两个条件的数据,再用这些数据回表。可能一开始有1000条数据,筛选过后就只有100条了,极大地减小了回表的压力和随机IO的次数。

所以索引下推,也可以称为索引条件下推,就相当于是在二级索引和主键索引之间的一道过滤墙,把一些不满足条件的数据先过滤掉,减轻了回表的压力。

六:关于select *select (具体字段)

        建议要查哪些字段就写哪些字段。

        首先,我们有可能不清楚表中到底有多少个字段,万一表非常大,你要查的数据又很少,那就得不偿失了。

        其次,mysql会对*进行解析,解析成对应字段名称,这是比较耗时的操作

        最后,select * 无法使用索引覆盖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Superzl1002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值