Explain详解与mysql索引最佳优化

萨瓦迪卡2周前 (08-19)MySql83

Explain工具介绍:

使用explain关键字可以模拟优化器执行sql语句,分析查询语句的或是结构的性能瓶颈。在select语句之前增加explain关键字,Mysql会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条sql
注意:如果from中包含子查询,仍会执行该子查询,将结果放入临时表中
explain语句 后面跟sql语句:
explain select * from actor;

explain两个变种(Mysql5.7以上不需要用变种了)

      (Mysql5.7以下版本需要变种显示partitions或filtered两个字段,5.7以上explain直接就有partitions和filtered这两个字段了):
1.explain extended:会在 explain 的基础上额外提供一些查询优化的信息。紧随其后通过 show warnings 命令可以得到优化后的查询语句,从而看出优化器优化了什么
filtered 列,是一个百分比的值,rows * filtered/100 可以估算出将要和 explain 中前一个表进行连接的行数(前一个表指 explain 中的id值比当前表id值小的表)。
explain extended select * from film where id =1;
show warnings 命令可以得到优化后的查询语句。
2explain partitions:相比 explain 多了个 partitions 字段,如果查询是基于分区表的话,会显示查询将访问的分区。

explain结果列:

1.id :id列的编号是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的。
最大值先执行,id列越大执行优先级越高,id相同则从上往下执行,id为Null最后执行。
2.select_type 查询类型:
simple:简单查询,查询语句不包含子查询和union
primary:复杂查询,最外层的select
derived:衍生查询(from后面的子查询语句)、
subquery:子查询,包含在 select 中的子查询(不在 from 子句中)
union:在 union 中的第二个和随后的 select
3.table表名
4.prtitions 如果查询是基于分区表的话,partitions 字段会显示查询将访问的分区
5.type关联类型或访问类型:system只查询有一条数据、const常量查询一样简单、eq_ref:主键或唯一索引关联,只返回一条记录,ref不使用唯一索引,而是使用普通索引或者唯一索引的前缀,可能会找到多个符合条件的行range:范围查找。index:扫描全索引就能拿到结果集,一般扫描某个二级索引(查整表无条件时优先使用二级索引查询,因为二级索引小) ,all:全表扫描,扫描聚集索引的所有叶子节点。
  • 优先级:system>const>eq_ref>ref>range>index>ALL.一般需要保证达到range级别,最好达到ref

  • ref与index的区别:ref是从根节点开始查找;index是全索引扫描(从叶子节点查找)。

  • index与all的区别:二级索引比主键索引效率高二级索引叶子节点只有 主键值,如果要查其他字段还要回表用主键索引查。All是走的主键索引的叶子节点

    8a04524e-1737-4b1a-86e6-b2744085787b.png

6.possible_key:可能会用到的索引
7.key:真正执行用到的索引
8.ken_len:使用的key的长度,比如联合索引的话,可以查看用了几个索引的长度。
9ref:查询条件的 字段值类型或字段
10.rows:计算这条sql语句可能要扫描多少行(预估值,不一定是实际值)。
11.extra列:
      • 如果是Using index覆盖索引,不会回表,直接在二级索引就查到结果了(也就是key值直接能查到)。

      • Using filesort:文件排序,没有走索引。

      • using where。直接用where语句就找打到结果,没走索引,key没有值

      • using index condition。不完全被索引覆盖,where条件里有范围查询

      • using temporary。用了临时表---可以优化成using index。给查询的字段加上索引即可

      • 如果为空,说明还要回表查主键 索引,查询除了id外的其他字段数据(走完key值,还要回表)。

mysql优化:

1索引列不要加函数,有函数不走索引(因为函数后的值在索引树里是无序的或是没有的)。
2.尽量使用覆盖索引,减少使用select *
3.where 使用!= 的 不走索引,导致全表扫描(不一定);
4.联合索引中 有字段使用了范围查找,范围条件右边的列不走索引。
EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age > 22 AND position ='manager';
5.is null ,is not null 一般情况下也不走索引。
6.like 模糊查询,以通配符%开头的会使索引失效,导致全表扫描。
  • 优化:用覆盖索引,查找字段少一点,尽量在索引里面。

7.字符串不加单引号,索引失效。或是关联字段类型不同,会导致索引失效。
8.少用or 或者in,不一定走索引。在数据量大的时候会走索引,表记录不多的时候会走全表扫面。mysql内部优化器会根据检索比例、表的大小等因素整体评估是否用索引,范围查询优化
9.联合索引,如果第一个字段如果是范围查询不走索引,mysql认为数据量大,宁愿走all。范围查询放在中间就走了。如果是>=又走了(前提是不能在第一个字段)。
      • 比如:explain select * from employees where name  > 'LiLei' and age = 22 and position = 'manager'

      • 强制走索引,不一定快:explain select * from employees  force  index(idx_name_age_position)  where name  > 'LiLei' and age = 22 and position = 'manager'

      • 关闭查询缓存量:set global query_cache_size = 0;set global query_cache_type = 0;

      • 索引下推:mysql 5.6以后 like查询开头的字段都用到了索引下推。


本文原创,转载必追究版权。

分享给朋友:

相关文章

js限制input只能输入数字、英文、汉字

 1.只能输入数字和英文的:  <input onkeyup="value=value.replace(/[\W]/g,'') "...

如何彻底卸载删除oracle数据库

 windows下如何彻底删除Oracle 软件环境: 1、Windows 2000+ORACLE 8.1.7 ,oracle 10g2、ORACLE安装路径为:C:\ORACLE实现方...

如何查询端口占用情况 并禁止占用

如何查询端口占用情况 并禁止占用

开始---->运行---->cmd,或者是window+R组合键,调出命令窗口输入命令:netstat -ano可看到是:pid为 2160 的程序占用了80端口;启动任务管理器:ctrl...

org.apache.subversion.javahl.ClientException: ¾ܾø·ÃÎʡ£ svn: Can't move 'E:\workspace\TourMarkets\.

org.apache.subversion.javahl.ClientException: ¾ܾø·ÃÎʡ£  svn: Can't move 'E:\workspace\T...

表单用submit提交前增加校验

有时由于各种原因 input 必须用submit类型提交,在表单提交前增加校验。直接附代码 <HTML>      <he...

js实现字符串 传参数 作为变量名 并为其赋值(动态变量名)

直接附代码,自己测试<html> <script> //例如:为变量x赋值1 xvalue('x','1');//变量名为:x,值为:1....

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。