mysql查询中利用EXPLAIN优化索引(简单易懂小白向)让你快速上手,适用于江湖救急!!!

Explain工具介绍

使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈  

在 select 语句之前增加 explain 关键字 ,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL

explain并不会执行sql语句仅仅只是模拟,因此很多东西并不绝对,需要具体分析,本文仅仅只是涉及到常见的列信息

最最最基础的应用(无需理解,用就完了)

一、explain用法

在你的查询语句select前加上explain

例如:explain select * from user where id = 0

二、字段认识

查询语句(不是具体的语句,仅仅举例子)

select * from (select age,gender from test where logout = 0)

 以上是我在项目中随意用一个查询语句explain产生的结果,先认识几个重要的列

1、id

该列表示执行先后,数字越大越先执行,相同数字从上往下。需要注意的是,查询语句中有几个select就有几行

2、table

字面意思该列表示的就是运行的是哪个表,图中第二行是具体的表名,第一行是表示派生表,也就是括号中的查询产生的表。

3、type

表示关联类型或访问类型。这个列大体上可以显示出一定程度上的查询速度了

优先级为:system > const > eq_ref > ref > range > index > ALL

一般情况下优化到ref就已经很快了,不过也遇到过index快于ref的时候,这就看具体表内数据和索引字段了

4、possible_keys

可能用到的索引,里面就是显示出了可能用到的所有索引的名称,如果出现null的情况就代表mysql认为用索引的帮助不大没必要

5、key

里面记录的就是正在使用的索引,如果你有多个索引,那要看看你的查询语句是否走的是你希望的那个索引

6、key_len

这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。 也就是说可以通过他来看看你的联合索引到底用了哪几个字段。计算方法可以自行上网查找,当然一般情况下小白也不太用的上

7、extra

一下就跳过了好几个列,因为如果仅仅是想要会用,不太需要了解那几列,而这一列是重中之重。

常见的信息有

(1)using index

走覆盖索引,也就是说如果select后面的字段全部在索引里面,就会显示这一列。很多情况下走了覆盖索引查询速度就已经不慢了。因此如果字段不多,可以尝试着将所有字段全部放在索引里,当然记得遵循最左前缀原则(简单点理解就是把索引的第一个字段设置为where后跟的第一个条件)

(2)using where

使用 where 语句来处理结果,并且查询的列未被索引覆盖。

(3)using index condition

查询的列不完全被索引覆盖,如果出现这一条信息,可以尝试着覆盖索引,一般情况下会提高查询性能

(4)using temporary

查询过程中出现了临时表,如果有这种情况那大概是需要优化了,去加索引吧骚年!

(5)using filesort

将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。

这种情况下一般也是要考虑使用索引来优化的。

三、索引优化

在这里不会说太多底层逻辑相关的东西,仅仅告诉大家怎么优化

注意:小白如果不理解为什么这样加可以多试几次这样加索引,先给他用会

同时尽量不要加单个索引,很多时候很难生效

1.where后面字段加联合索引

一定!一定!一定要按照顺序加进去,不然查询速度会慢的超乎你想象,同时不要跳过索引中的字段,也就是说如果索引有a.b.c三个字段,如果你查询的条件里没有a,那索引就不生效,或者中间跳过了b也不生效,其他的ab,abc,ac,a都会生效。

当使用mybatis动态sql时,则需要考虑到底是加abc还是ab还是bc或者bac等组合,仔细思考

2.group by/order by后字段加索引

在优化中你可以把这两个条件后的字段看做where的一种(仅仅是看做啊,方便你理解怎么加索引而已)

3.尽量使用覆盖索引,减少select *

与一些博客说的不同,select * 不一定会导致索引失效,但是仅仅只是查询需要的字段就会减少很多时间,而且如果需要的字段少,走覆盖索引速度会非常快

4.is null,is not null 一般情况下无法使用索引

5.字符串不加单引号索引失效

在条件中有字符串时,一定要加单引号

6.mysql在使用不等于(!=或者<>),not in ,not exists 的时候无法使用索引会导致全表扫描

当然也有使用了但不会全表扫描的情况,这主要是看mysql底层判断,最好避免

7.like以通配符开头('$abc...')mysql索引失效会变成全表扫描操作

优化方案:如果无奈必须以通配符开头,那就尽量减少字段走覆盖索引

8.不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描

9.范围查询优化

mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引。可能是由于单次数据量查询过大导致优化器最终选择不走索引

优化方法:可以将大的范围拆分成多个小范围

10.少用or或in

用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引

11.能用where就不要用having

总结:

一、重点有两点

1.尽量将type列里的信息优化到ref甚至eq_ref

2.尽量将extra里的信息优化到没有using temporary和using filesort

二、explain的信息并不绝对,因为它不会执行sql,因此很多时候还是需要自己去判断。如果有时间还是更多地去学习索引底层的逻辑,该文章仅仅适用于江湖救急,因为本人刚实习就是啥都不会,然后看博客也感觉很冗余,用不上的信息太多碰了很多壁。

三、以上很多东西都不是绝对的,mysql很多时候会出现一些奇奇怪怪的东西,所以需要具体情况具体分析,它虽然会自动给我们优化sql,但我也碰到过我强制走另一个索引速度更快的。

在看完文章江湖救急之后,还是要自己学习更深的东西,该文章仅仅只是冰山一角而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值