加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL中通过EXPLAIN怎样分析SQL的执行计划详解

发布时间:2022-03-13 23:41:34 所属栏目:MySql教程 来源:互联网
导读:在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。 MySQL中通过EXPLAIN如何分析SQL的执行计划详解 下面分别对EXPLAIN命令结果的每一列进行说明: .select_type:表示SELECT的类型,
  在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。
 
  MySQL中通过EXPLAIN如何分析SQL的执行计划详解
 
  下面分别对EXPLAIN命令结果的每一列进行说明:
 
  .select_type:表示SELECT的类型,常见的取值有:
 
  类型 说明
  SIMPLE 简单表,不使用表连接或子查询
  PRIMARY 主查询,即外层的查询
  UNION UNION中的第二个或者后面的查询语句
  SUBQUERY 子查询中的第一个
  .table:输出结果集的表(表别名)
 
  .type:表示MySQL在表中找到所需行的方式,或者叫访问类型。常见访问类型如下,从上到下,性能由差到最好:
 
  ALL 全表扫描
  index 索引全扫描
  range 索引范围扫描
  ref 非唯一索引扫描
  eq_ref 唯一索引扫描
  const,system 单表最多有一个匹配行
  NULL 不用扫描表或索引
  1、type=ALL,全表扫描,MySQL遍历全表来找到匹配行
 
  一般是没有where条件或者where条件没有使用索引的查询语句
 
  EXPLAIN SELECT * FROM customer WHERE active=0;
  MySQL中通过EXPLAIN如何分析SQL的执行计划详解
 
  2、type=index,索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表
 
  一般是查询的字段都有索引的查询语句
 
  EXPLAIN SELECT store_id FROM customer;
  MySQL中通过EXPLAIN如何分析SQL的执行计划详解
 
  3、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的执行计划详解
 
  ref类型还经常会出现在join操作中:
 
  customer、payment表关联查询,关联字段customer.customer_id(主键),payment.customer_id(非唯一索引)。表关联查询时必定会有一张表进行全表扫描,此表一定是几张表中记录行数最少的表,然后再通过非唯一索引寻找其他关联表中的匹配行,以此达到表关联时扫描行数最少。
 
  因为customer、payment两表中customer表的记录行数最少,所以customer表进行全表扫描,payment表通过非唯一索引寻找匹配行。
 
  EXPLAIN SELECT * FROM customer customer INNER JOIN payment payment ON customer.customer_id = payment.customer_id;
 
  4、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;
 
  5、type=const/system,单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理
 
  const/system出现在根据主键primary key或者 唯一索引 unique index 进行的查询
 
  根据主键primary key进行的查询:
 
  EXPLAIN SELECT * FROM customer WHERE customer_id =10;
 
  根据唯一索引unique index进行的查询:
 
  EXPLAIN SELECT * FROM customer WHERE email ='MARY.SMITH@sakilacustomer.org';
 
 6、type=NULL,MySQL不用访问表或者索引,直接就能够得到结果
 
  .possible_keys: 表示查询可能使用的索引
 
  .key: 实际使用的索引
 
  .key_len: 使用索引字段的长度
 
  .ref: 使用哪个列或常数与key一起从表中选择行。
 
  .rows: 扫描行的数量
 
  .filtered: 存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例(百分比)
 
  .Extra: 执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息
 
  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优化。

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!