mysql中explain命令详解

前言

我们可以使用 explain 命令来查看 SQL 语句的执行计划,从而帮助我们优化慢查询。

使用

注意:使用的 mysql 版本为 8.0.28

数据准备

CREATE TABLE `tb_product2` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `name` varchar(20) DEFAULT NULL COMMENT '商品名称',
  `en_name` varchar(20) DEFAULT NULL COMMENT '商品英文名称',
  `stock` int DEFAULT NULL COMMENT '库存量',
  PRIMARY KEY (`id`),
  index `index_name`(`name`)
) ENGINE=InnoDB;

CREATE TABLE `tb_order2` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `product_id` bigint DEFAULT NULL COMMENT '商品ID',
  `quantity` int DEFAULT NULL COMMENT '购买数量',
  `price` decimal(10,2) DEFAULT NULL COMMENT '订单总金额',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

INSERT INTO `tb_product2`( `name`, `en_name` , `stock` ) VALUES('苹果11', 'iphone11', 10); 
INSERT INTO `tb_product2`( `name`, `en_name` , `stock` ) VALUES('小米6', 'xiaomi6', 20); 
INSERT INTO `tb_order2`( `product_id`, `quantity` , `price`, `create_time`) VALUES(1, 5, 100.00, now()); 
INSERT INTO `tb_order2`( `product_id`, `quantity` , `price` , `create_time`) VALUES(2, 3, 60.00, now()); 

查询执行计划

EXPLAIN SELECT * FROM `tb_product2` WHERE id = 1;

结果为

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tb_product2 null const PRIMARY PRIMARY 8 const 1 100.00 null
EXPLAIN SELECT * FROM `tb_product2` WHERE en_name = 'xiaomi6';

结果为

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tb_product2 null ALL null null null null 2 50.00 Using where

字段详解

id

每次select查询都会对应一个id,它代表着SQL执行的顺序,如果id值越大,说明对应的SQL语句执行的优先级越高。

image

select_type

表示执行计划对应的查询类型,常见的查询类型主要包括普通查询、联合查询以及子查询等。

  • simple: 简单的select查询,没有union或者子查询
  • primary: 有嵌套查询时的最外层的select查询
  • derived: 用来表示包含在FROM子句的子查询中的SELECT,MySQL会递归执行并将结果放到一个临时表中。MySQL内部将其称为是Derived table(派生表),因为该临时表是从子查询派生出来的
  • union: union中的第二个或随后的select查询,不依赖于外部查询的结果集
  • dependent union: union中的第二个或随后的select查询,依赖于外部查询的结果集
  • subquery: 子查询中的第一个select查询,不依赖与外部查询的结果集
  • dependent subquery: 子查询中的第一个select查询,依赖于外部查询的结果集

table

表示要查询哪张表,当然不一定是真实的表的名称,也可能是表的别名或者临时表。

partitions

表示在进行查询时,如果对应的表存在分区表,那么这里就会显示具体的分区信息。

type

type是非常核心的属性,需要重点掌握。它表示的是当前通过什么样的方式对数据库表进行访问。

  • system: 该表只有一行(相当于系统表),数据量很小,查询速度很快,system是const类型的特例。
    image
  • const: 在进行数据查询的时候,命中了primary key或唯一索引,此类数据查询速度非常快。
  • eq_ref: 对于每个来自于前面的表的行组合,从该表中读取一行,常用在一个索引是unique key或者primary key。
  • ref: 数据查询的时候如果命中的索引是二级索引不是唯一索引,测试查询速度也会很快,但是type是ref。另外如果是多字段的联合索引,那么根据最左匹配原则,从联合索引的最左侧开始连续多个列的字段进行等值比较也是ref的类型。
  • ref_or_null: 类似于 ref,区别在于 MySQL会额外搜索包含NULL值的行。
  • unique_subquery: 在where条件中的关于in的子查询条件集合。
  • index_subquery: 区别于unique_subquery,用于非唯一索引,可以返回重复值。
  • range: 使用索引进行行数据检索,只对指定范围内的行数据进行检索。换句话说就是针对一个有索引的字段,在指定范围中检索数据。在where语句中使用 bettween...and、<、>、<=、in 等条件查询 type 都是 range。
    image
  • all: 遍历全表进行数据匹配,此时的数据查询性能最差。
    image
  • index: index 与 all 其实都是读全表,区别在于index是遍历索引树读取,而ALL是从硬盘中读取。

possible_keys

表示哪些索引可以被 MySQL 的优化器进行选择,也就是索引候选者有哪些。

key

最终选择使用的索引。

key_len

表示索引的长度,和实际的字段属性以及是否为null都有关系。

ref

当使用字段进行常量等值查询时ref此处为const,当查询条件中使用了表达式或者函数则ref显示为func,其他的显示为null。

rows

表示 MySQL 认为它执行查询时必须检查的行数。行数越少,效率越高。

filtered

这个是一个百分比的值,表里符合条件的记录数的百分比。简单点说,这个字段表示存储引擎返回的数据在经过过滤后,剩下的满足条件的记录数量的比例。

extra

在其他列不显示额外信息在此列进行展示。

  • Using index: 在进行数据查询的时候,数据库使用了覆盖索引,就是查询的列被索引覆盖,使用到覆盖索引查询速度会非常快。
    image
  • Using where: 查询时未找到可用的索引,进而通过where条件过滤获取所需数据,但要注意的是并不是所有带where语句的查询都会显示Using where。
  • Using temporary: 表示查询后结果需要使用临时表来存储,一般在排序或者分组查询时用到。
  • Using filesort: 此类型表示无法利用索引完成指定的排序操作,也就是ORDER BY的字段实际没有索引,因此此类SQL是需要进行优化的。

参考

Mysql的explain,你真的会用吗?
MySQL优化之EXPLAIN命令解析
全网最全 | MySQL EXPLAIN 完全解读
Mysql中key 、primary key 、unique key 与index区别

posted @ 2024-05-15 22:01  strongmore  阅读(16)  评论(0编辑  收藏  举报