Mysql:EXPLAIN命令

两种用法

  • 可以EXPLAIN table_name,效果和DESC table_name相同(和SHOW CREATE TABLE table_name不同,后者会查询出建表语句)
    Mysql:EXPLAIN命令_第1张图片
SHOW CREATE TABLE game_interest_user_data

CREATE TABLE `game_interest_user_data` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `user_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1:cuid, 2:uid',
  `user_id` varchar(60) NOT NULL DEFAULT '0' COMMENT '用户id',
  `interest_id` bigint(11) NOT NULL COMMENT '游戏id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_type` (`user_type`,`user_id`,`interest_id`),
  KEY `interest_id` (`interest_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12182 DEFAULT CHARSET=utf8 COMMENT='用户兴趣表'
  • 也可以EXPLAIN SELECT...,即EXPLAIN后接SELECT语句。如果UPDATE或DELECT语句需要优化,则需要先改为SELECT,如:
UPDATE table_name SET col1 = 'X' , col2 = 'Y' WHERE id = 9 AND dt >= '2020-01-01'
可以被改为
SELECT col1, col2 FROM table_name WHERE id = 9 AND dt>= '2020-01-01'

EXPLAIN各列详解

  • id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
  • 例如:
EXPLAIN SELECT game_interest.id,game_interest.name,COUNT(*) FROM game_interest_user_data INNER JOIN game_interest ON game_interest_user_data.interest_id = game_interest.id GROUP BY game_interest.id ORDER BY 3 DESC;
  • game_interest_user_data.interest_id加索引之前:
    在这里插入图片描述
  • game_interest_user_data.interest_id加索引之后:
    在这里插入图片描述

id

  • id相同时,从上向下顺序执行。
  • id不同时,越大的优先级越高。

select_type

  • 查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询。
  • 常见类型有:SIMPLE、PRIMARY、DERIVED、SUBQUERY和UNION。
  • SIMPLE:不包含子查询和其他复杂语法。
  • PRIMARY:包含复杂查询的最外层的表。
  • DERIVED:衍生表(临时表),在FROM后跟的子查询标记为DERIVED。
  • SUBQUERY:SELECT或WHERE中的子查询。(并非所有)
  • UNION:UNION语句其中的一个SELECT。
  • UNION RESULT:从UNION语句查询的SELECT。

type

  • 执行计划中指定的表使用的连接方式。
  • const:当表最多只有一行匹配时出现,比如使用主键或唯一索引作为查询条件
  • system:这是const特例,当表只有一行时出现,通常是系统表。
  • eq_ref:在多个表联表时使用主键或唯一索引作为连接条件(只需要使用其中一个表的主键或唯一索引即可)。
  • ref:联表使用了非唯一索引。
  • range:检索给定范围的行,比如在WHERE语句中使用了BETWEEN、LIKE等。
  • index:遍历索引树。
  • ALL:扫描全表,从硬盘中读。

possible_keys

  • 查询涉及到的字段上存在索引,则会被列出,并不一定使用。

key

  • 表示优化器选择使用的索引,如:
key: item_id
key: NULL
key: first, last
  • 覆盖索引可以只出现在key列,而不出现在possible_keys列,如:
EXPLAIN SELECT user_id, interest_id FROM game_interest_user_data 

在这里插入图片描述

  • 当查询的列不在覆盖索引中时,会变为全表扫描。
EXPLAIN SELECT user_id, interest_id,create_time FROM game_interest_user_data 

在这里插入图片描述

key_len

  • 表示索引字节数,只和WHERE和JOIN中的索引列有关,如:
EXPLAIN SELECT user_id, interest_id FROM game_interest_user_data WHERE user_type = 1 AND user_id = 'XXXX'

在这里插入图片描述

  • 183 = 1 + 60 * 3 + 2,1是user_type长度,60*3 + 2是user_id长度
  • 是否可以为NULL,可变长度的列(比如VARCHAR(30)和CHAR(30)长度不同)以及字符集都会影响到表索引的大小。

ref

  • 表示使用索引时,索引与哪些数据关联。可能是其他表的某字段,也可能是常量。

Extra

  • Using filesort:排序没用到索引,需要额外排序。参考
  • Using temporary:需要创建临时表,通常时因为联表时使用了DISTINCT,或者使用了不同的
  • Using where:使用索引不能满足条件,需要使用where过滤。
  • Using index:使用了覆盖索引,避免了回表。
  • Using index condition:5.6版本引入的新特性,表示索引下推,对索引包含的列优先判断,减少回表次数。
-- 当没有interest_id单列索引时
EXPLAIN SELECT * FROM game_interest_user_data WHERE user_type = 2 AND user_id = 1463335901 AND interest_id = 2;

在这里插入图片描述

你可能感兴趣的:(Mysql)