MySQL如何通过EXPLAIN分析SQL的执行计划

MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。

mark

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

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

类型说明
SIMPLE   简单表,不使用表连接或子查询  
PRIMARY   主查询,即外层的查询  
UNION   UNION中的第二个或者后面的查询语句  
SUBQUERY   子查询中的第一个  

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

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

ALL全表扫描
index   索引全扫描  
range   索引范围扫描  
ref   非唯一索引扫描  
eq_ref   唯一索引扫描  
const,system   单表最多有一个匹配行  
NULL   不用扫描表或索引  

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

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

EXPLAIN SELECT * FROM customer WHERE active=0;

mark

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

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

EXPLAIN SELECT store_id FROM customer;

mark

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

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

mark

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

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

mark

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

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

EXPLAIN SELECT * FROM customer WHERE store_id=10;

mark

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

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

mark

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

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

mark

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;

mark

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/751bfb8a28b8311f1c232e9e0c9e7b24.html