本文主要通过EXPLAIN来介绍在MySQL中如何分析SQL的执行计划的相关信息。通过图片和实例非常详细的介绍,对大家的学习或者工作都有一定的学习价值。下面让我们跟随边肖一起学习。
前言
在MySQL中,我们可以通过EXPLAIN命令得到MySQL如何执行SELECT语句的信息,包括SELECT语句执行过程中表是如何连接的,以及连接的顺序。
解释命令结果的每一列解释如下:
.select_type:
表示选择的类型。常见的值有:类型
解释
简单的
简单表,没有表连接或子查询。
主要的
主查询,即外部查询。
联盟
UNION中的第二个或后续查询语句
子查询
子查询中的第一个。
.table:
输出结果集的表(表别名).type:
表示MySQL在表中找到所需行的方式,或访问类型。常见的访问类型如下,从上到下,性能从差到好:全部
全表扫描
指数
索引全扫描
范围
索引范围扫描
裁判员
非唯一索引扫描
eq_ref
唯一索引扫描
系统常数
一个表最多有一个匹配行。
空
不扫描表或索引
1、type=ALL,全表扫描,MySQL遍历全表来找到匹配行
一般是没有where条件或者where条件没有索引的查询语句。
解释SELECT * FROM客户,其中active=0;
2、type=index,索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表
通常,它是一个查询语句,其中查询的字段被索引。
解释SELECT store _ id FROM customer
3、type=range,索引范围扫描,常用于、=、、=、between等操作
解释SELECT * FROM customer,其中customer_id=10,customer _ id=20
注意
在这种情况下,需要对要比较的字段进行索引。如果没有索引,MySQL将扫描整个表。如下例所示,create_date字段没有索引:解释SELECT * FROM customer WHERE create _ date= 2006-02-13 ;
4、type=ref,使用非唯一索引或唯一索引的前缀扫描,返回匹配某个单独值的记录行
store_id字段中有一个公共索引(非唯一索引)。
解释SELECT * FROM customer WHERE store _ id=10;
引用类型也经常出现在连接操作中:
客户,付款表联查,关联字段customer.customer_id(主键),payment.customer_id(非唯一索引)。表关联查询时,必须扫描一个表。这个表必须是几个表中行数最少的一个,然后通过非唯一索引找到其他关联表中匹配的行,以达到表关联时扫描的行数最少。
因为customer表在customer和payment表中记录的行数最少,所以customer表扫描整个表,payment表通过非唯一索引搜索匹配的行。
解释SELECT * FROM customer customer INNER JOIN payment payment ON customer . customer _ id=payment . customer _ id;
5、type=eq_ref,类似ref,区别在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配
Eq_ref一般出现在连接多个表时,使用主键或唯一索引作为关联条件。
film和film_text表的联查基本和上一篇文章提到的一样,只是关联条件由非唯一索引改为主键。
解释SELECT * FROM film film INNER JOIN film _ text film _ text ON film . film _ id=film _ text . film _ id;
6、type=const/system,单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理
Const/system出现在基于主键或唯一索引unique index的查询中。
基于主键主键的查询:
解释SELECT * FROM customer,其中customer _ id=10
基于唯一索引的查询:
解释SELECT * FROM客户,其中email=MARY。SMITH @ sakila customer . org ;
7、type=NULL,MySQL不用访问表或者索引,直接就能够得到结果
.possible_keys:
表示查询可能使用的索引。实际使用的
.key:
指数.key_len:
使用索引字段的长度.ref:
与key一起使用的列或常数,用于从表中选择行。.rows:
扫描行数.filtered:
存储引擎返回的数据在服务器层过滤后满足查询的记录数的比例(百分比)。.Extra:
实施情况的描述和说明,包括不适合在其他栏中显示但对实施计划非常重要的附加信息。最重要的有以下三种:
使用索引
指示索引覆盖率,并且不会返回到表查询。
使用哪里
它表示已经进行了表返回查询。
使用索引条件
这表明执行了ICP优化。
使用Flesort
意味着MySQL需要额外的排序操作,排序效果无法通过索引顺序来实现。
什么是ICP?
MySQL5.6引入了索引条件下推(ICP)特性来进一步优化查询。下推意味着操作分散化。在某些情况下,条件筛选操作被分散到存储引擎。
解释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和customer _ ID=400(在服务层完成)筛选出最终的查询结果。
在5.6版本之后:
MySQL ICP用于进一步优化查询。搜索时,customer _ id=300和customer _ id=400的条件也被推送到存储引擎层完成过滤,可以减少不必要的IO访问。Extra是使用索引条件,这意味着使用ICP优化。
涉及
《深入浅出MySQL》
总结
这就是本文的全部内容。希望这篇文章的内容对你的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。