MySQL—EXPLAIN分析SQL的具体执行计划

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。MySQL—EXPLAIN分析SQL的具体执行计划,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

简述:在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。但是很多时候都是用的时候才想起那个字段代表了什么?因此记录一个文档来看看每个Explain值的代表。

MySQL—EXPLAIN分析SQL的具体执行计划

下面分别对EXPLAIN命令结果的每一列进行说明:

一、select_type

  • select_type:表示SELECT的类型,常见的取值有:

类型

说明

SIMPLE

简单表,不使用表连接或子查询

PRIMARY

主查询,即外层的查询

UNION

UNION中的第二个或者后面的查询语句

SUBQUERY

子查询中的第一个

二、table

  • table:输出结果集的表(表别名)

三、type

  • type:表示MySQL在表中找到所需行的方式,或者叫访问类型。常见访问类型如下,从上到下,性能由差到最好:

ALL

全表扫描

index

索引全扫描

range

索引范围扫描

ref

非唯一索引扫描

eq_ref

唯一索引扫描

const,system

单表最多有一个匹配行

NULL

不用扫描表或索引

  • type=ALL,全表扫描,MySQL遍历全表来找到匹配行

一般是没有where条件或者where条件没有使用索引的查询语句

EXPLAIN SELECT * FROM customer WHERE active=0;

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=index,索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表

一般是查询的字段都有索引的查询语句

EXPLAIN SELECT store_id FROM customer;

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=range,索引范围扫描,常用于<、<=、>、>=、between等操作

EXPLAIN SELECT * FROM customer WHERE customer_id>=10 AND customer_id<=20;

MySQL—EXPLAIN分析SQL的具体执行计划

 

注意这种情况下比较的字段是需要加索引的,如果没有索引,则MySQL会进行全表扫描,如下面这种情况,create_date字段没有加索引:

EXPLAIN SELECT * FROM customer WHERE create_date>=’2006-02-13′ ;

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=ref,使用非唯一索引或唯一索引的前缀扫描,返回匹配某个单独值的记录行

store_id字段存在普通索引(非唯一索引)

EXPLAIN SELECT * FROM customer WHERE store_id=10;

MySQL—EXPLAIN分析SQL的具体执行计划

 

ref类型还经常会出现在join操作中:

customerpayment表关联查询,关联字段customer.customer_id(主键),payment.customer_id(非唯一索引)。表关联查询时必定会有一张表进行全表扫描,此表一定是几张表中记录行数最少的表,然后再通过非唯一索引寻找其他关联表中的匹配行,以此达到表关联时扫描行数最少。

MySQL—EXPLAIN分析SQL的具体执行计划

 

因为customerpayment两表中customer表的记录行数最少,所以customer表进行全表扫描,payment表通过非唯一索引寻找匹配行。

EXPLAIN SELECT * FROM customer customer INNER JOIN payment payment ON customer.customer_id = payment.customer_id;

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=eq_ref,类似ref,区别在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配

eq_ref一般出现在多表连接时使用primary key或者unique index作为关联条件。

film、film_text表关联查询和上一条所说的基本一致,只不过关联条件由非唯一索引变成了主键。

EXPLAIN SELECT * FROM film film INNER JOIN film_text film_text ON film.film_id = film_text.film_id;

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=const/system,单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理

const/system出现在根据主键primary key或者 唯一索引 unique index 进行的查询

根据主键primary key进行的查询:

EXPLAIN SELECT * FROM customer WHERE customer_id =10;

MySQL—EXPLAIN分析SQL的具体执行计划

 

根据唯一索引unique index进行的查询:

EXPLAIN SELECT * FROM customer WHERE email =’MARY.SMITH@sakilacustomer.org’;

 

MySQL—EXPLAIN分析SQL的具体执行计划

MySQL—EXPLAIN分析SQL的具体执行计划

 

  • type=NULL,MySQL不用访问表或者索引,直接就能够得到结果

MySQL—EXPLAIN分析SQL的具体执行计划

四、possible_keys

  • possible_keys: 表示查询可能使用的索引

MySQL—EXPLAIN分析SQL的具体执行计划

五、key

  • key: 实际使用的索引

MySQL—EXPLAIN分析SQL的具体执行计划

六、key_len

  • key_len: 使用索引字段的长度

七、ref

  • ref: 使用哪个列或常数与key一起从表中选择行。

八、rows

  • rows: 扫描行的数量

九、filtered

  • filtered: 存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例(百分比)

十、Extra

  • Extra: 执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息

最主要的有一下三种:

Using Index

表示索引覆盖,不会回表查询

Using Where

表示进行了回表查询

Using Index Condition

表示进行了ICP优化

Using Flesort

表示MySQL需额外排序操作, 不能通过索引顺序达到排序效果

十一、扩展:如果我们有多个索引,某个索引效率会更高,那么该怎么做:

1:平常情况

EXPLAIN
   SELECT family_id FROM family_member 
       WHERE family_id = 16943  ;

MySQL—EXPLAIN分析SQL的具体执行计划

2:我只用某个索引情况

EXPLAIN
    SELECT family_id FROM family_member 
          FORCE INDEX( family_info_id ) WHERE family_id = 16943  ;

MySQL—EXPLAIN分析SQL的具体执行计划

这样就只用某一个索引了。

第十二:扩展 什么是ICP

MySQL5.6引入了Index Condition Pushdown(ICP)的特性,进一步优化了查询。Pushdown表示操作下放,某些情况下的条件过滤操作下放到存储引擎。

EXPLAIN SELECT * FROM rental WHERE rental_date=’2005-05-25′ AND customer_id>=300 AND customer_id<=400;

在5.6版本之前:

优化器首先使用复合索引idx_rental_date过滤出符合条件rental_date=’2005-05-25′的记录,然后根据复合索引idx_rental_date回表获取记录,最终根据条件customer_id>=300 AND customer_id<=400过滤出最后的查询结果(在服务层完成)。

在5.6版本之后:

MySQL使用了ICP来进一步优化查询,在检索的时候,把条件customer_id>=300 AND customer_id<=400也推到存储引擎层完成过滤,这样能够降低不必要的IO访问。Extra为Using index condition就表示使用了ICP优化。

MySQL—EXPLAIN分析SQL的具体执行计划

文献参考来自:

MYSQL-通过EXPLAIN分析SQL的执行计划

强制指定使用某一索引的例子

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/160904.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!