https://blog.csdn.net/u011383596/article/details/108092176
我们都知道用explain xxx分析sql语句的性能,但是具体从explain的结果怎么分析性能以及每个字段的含义你清楚吗?这里我做下总结记录,也是供自己以后参考。

首先需要注意:MYSQL 5.6.3以前只能EXPLAIN SELECT; MYSQL5.6.3以后就可以EXPLAIN SELECT,UPDATE,DELETE
explain结果示例:

mysql> explain select * from staff;
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| 1 | SIMPLE | staff | ALL | NULL | NULL | NULL | NULL | 2 | NULL |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
1 row in set
先上一个官方文档表格的中文版:

Column 含义
id 查询序号
select_type 查询类型
table 表名
partitions 匹配的分区
type join类型
prossible_keys 可能会选择的索引
key 实际选择的索引
key_len 索引的长度
ref 与索引作比较的列
rows 要检索的行数(估算值)
filtered 查询条件过滤的行数的百分比
Extra 额外信息
这是explain结果的各个字段,分别解释下含义:

  1. id
    SQL查询中的序列号。

id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行。

  1. select_type
    查询的类型,可以是下表的任何一种类型:

select_type 类型说明
SIMPLE 简单SELECT(不使用UNION或子查询)
PRIMARY 最外层的SELECT
UNION UNION中第二个或之后的SELECT语句
DEPENDENT UNION UNION中第二个或之后的SELECT语句取决于外面的查询
UNION RESULT UNION的结果
SUBQUERY 子查询中的第一个SELECT
DEPENDENT SUBQUERY 子查询中的第一个SELECT, 取决于外面的查询
DERIVED 衍生表(FROM子句中的子查询)
MATERIALIZED 物化子查询
UNCACHEABLE SUBQUERY 结果集无法缓存的子查询,必须重新评估外部查询的每一行
UNCACHEABLE UNION UNION中第二个或之后的SELECT,属于无法缓存的子查询
DEPENDENT 意味着使用了关联子查询。

  1. table
    查询的表名。不一定是实际存在的表名。
    可以为如下的值:

<unionM,N>: 引用id为M和N UNION后的结果。
: 引用id为N的结果派生出的表。派生表可以是一个结果集,例如派生自FROM中子查询的结果。
: 引用id为N的子查询结果物化得到的表。即生成一个临时表保存子查询的结果。
4. type(重要)
这是最重要的字段之一,显示查询使用了何种类型。从最好到最差的连接类型依次为:

system,const,eq_ref,ref,fulltext,ref_or_null,index_merge,unique_subquery,index_subquery,range,index,ALL

除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。

1、system

表中只有一行数据或者是空表,这是const类型的一个特例。且只能用于myisam和memory表。如果是Innodb引擎表,type列在这个情况通常都是all或者index

2、const

最多只有一行记录匹配。当联合主键或唯一索引的所有字段跟常量值比较时,join类型为const。其他数据库也叫做唯一索引扫描

3、eq_ref

多表join时,对于来自前面表的每一行,在当前表中只能找到一行。这可能是除了system和const之外最好的类型。当主键或唯一非NULL索引的所有字段都被用作join联接时会使用此类型。

eq_ref可用于使用’='操作符作比较的索引列。比较的值可以是常量,也可以是使用在此表之前读取的表的列的表达式。

相对于下面的ref区别就是它使用的唯一索引,即主键或唯一索引,而ref使用的是非唯一索引或者普通索引。
eq_ref只能找到一行,而ref能找到多行。

4、ref

对于来自前面表的每一行,在此表的索引中可以匹配到多行。若联接只用到索引的最左前缀或索引不是主键或唯一索引时,使用ref类型(也就是说,此联接能够匹配多行记录)。

ref可用于使用’=‘或’<=>'操作符作比较的索引列。

5、 fulltext

使用全文索引的时候是这个类型。要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引

6、ref_or_null

跟ref类型类似,只是增加了null值的比较。实际用的不多。

eg.
SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;
7、index_merge

表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取多个索引,性能可能大部分时间都不如range

8、unique_subquery

用于where中的in形式子查询,子查询返回不重复值唯一值,可以完全替换子查询,效率更高。
该类型替换了下面形式的IN子查询的ref:
value IN (SELECT primary_key FROM single_table WHERE some_expr)

9、index_subquery

该联接类型类似于unique_subquery。适用于非唯一索引,可以返回重复值。

10、range

索引范围查询,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中。

SELECT * FROM tbl_name
WHERE key_column BETWEEN 10 and 20;

SELECT * FROM tbl_name
WHERE key_column IN (10,20,30);
11、index

索引全表扫描,把索引从头到尾扫一遍。这里包含两种情况:
一种是查询使用了覆盖索引,那么它只需要扫描索引就可以获得数据,这个效率要比全表扫描要快,因为索引通常比数据表小,而且还能避免二次查询。在extra中显示Using index,反之,如果在索引上进行全表扫描,没有Using index的提示。

此表见有一个name列索引。

因为查询的列name上建有索引,所以如果这样type走的是index

mysql> explain select name from testa;
±—±------------±------±------±--------------±---------±--------±-----±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±------±--------------±---------±--------±-----±-----±------------+
| 1 | SIMPLE | testa | index | NULL | idx_name | 33 | NULL | 2 | Using index |
±—±------------±------±------±--------------±---------±--------±-----±-----±------------+
1 row in set

因为查询的列cusno没有建索引,或者查询的列包含没有索引的列,这样查询就会走ALL扫描,如下:

mysql> explain select cusno from testa;
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| 1 | SIMPLE | testa | ALL | NULL | NULL | NULL | NULL | 2 | NULL |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
1 row in set

包含有未见索引的列

mysql> explain select * from testa;
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
| 1 | SIMPLE | testa | ALL | NULL | NULL | NULL | NULL | 2 | NULL |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------+
1 row in set
12、all

全表扫描,性能最差。

  1. partitions
    版本5.7以前,该项是explain partitions显示的选项,5.7以后成为了默认选项。该列显示的为分区表命中的分区情况。非分区表该字段为空(null)。

  2. possible_keys
    查询可能使用到的索引都会在这里列出来

  3. key
    查询真正使用到的索引。
    select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

  4. key_len
    查询用到的索引长度(字节数)。
    如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,用多少算多少。留意下这个列的值,算一下你的多列索引总长度就知道有没有使用到所有的列了。

key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。

  1. ref
    如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func

  2. rows(重要)
    rows 也是一个重要的字段。 这是mysql估算的需要扫描的行数(不是精确值)。
    这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好.

  3. filtered
    这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。这个字段不重要

  4. extra(重要)
    EXplain 中的很多额外的信息会在 Extra 字段显示, 常见的有以下几种内容:

distinct:在select部分使用了distinc关键字
Using filesort:当 Extra 中有 Using filesort 时, 表示 MySQL 需额外的排序操作, 不能通过索引顺序达到排序效果. 一般有 Using filesort, 都建议优化去掉, 因为这样的查询 CPU 资源消耗大.

例如下面的例子:

mysql> EXPLAIN SELECT * FROM order_info ORDER BY product_name \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: index
possible_keys: NULL
key: user_product_detail_index
key_len: 253
ref: NULL
rows: 9
filtered: 100.00
Extra: Using index; Using filesort
1 row in set, 1 warning (0.00 sec)
我们的索引是

KEY user_product_detail_index (user_id, product_name, productor)
但是上面的查询中根据 product_name 来排序, 因此不能使用索引进行优化, 进而会产生 Using filesort.
如果我们将排序依据改为 ORDER BY user_id, product_name, 那么就不会出现 Using filesort 了. 例如:

mysql> EXPLAIN SELECT * FROM order_info ORDER BY user_id, product_name \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_info
partitions: NULL
type: index
possible_keys: NULL
key: user_product_detail_index
key_len: 253
ref: NULL
rows: 9
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
Using index
“覆盖索引扫描”, 表示查询在索引树中就可查找所需数据, 不用扫描表数据文件, 往往说明性能不错

Using temporary
查询有使用临时表, 一般出现于排序, 分组和多表 join 的情况, 查询效率不高, 建议优化.

除此之外还有其他值,这里就不一一一列举了。

explan 结果每个字段说明相关推荐

  1. mysql 字段解释_MySQL EXPLAN 字段结果解释

    EXPLAN 显示的是 MySql 如何使用索引和对SQL进行分析的工具.用来查看索引是否生效,关联查询具体情况等信息. 调用 EXPLAN 只需要在查询语句 SELECT 前增加 EXPLAN 这个 ...

  2. 3、Explan执行计划

    目录 explain中的列说明 1.id 2.select_type ​        3.table列 4. type列 NULL: system,const: eq_ref ref range i ...

  3. 史上最详细的mysql底层和explan type和type中index和all的区别

    背景: 前几天我朋友问我一个问题,mysql的explan(执行计划)中type的index和all是不是压根没有区别,而且还推了几个博主的链接给我,我看了之后感觉有些无奈,有些博主自己都没有太搞清楚 ...

  4. Mysql 系列2 一 explan

    一.那些情况需要创建索引? 1.主键自动建立唯一索引: 2.频繁作为查询条件的字段应该创建索引: 3.查询中与其他表关联的字段,外键关系建立索引: 4.频繁更新的字段不适合创建索引,因为每次更新不单单 ...

  5. MySQL数据库——EXPLAN预执行

    概念理解 作用:模拟优化器执行 sql 查询语句,从而知道Mysql是如何处理该 sql 语句的. 用法:EXPLAN + 原 sql 语句. 结果:返回执行信息. 返回结果 id select_ty ...

  6. MySQL性能分析工具的使用:慢查询日志、EXPLAN的使用、分析优化器执行计划:trace、MySQL监控分析视图-sys schema

    文章目录 1.数据库服务器的优化步骤 2.查看系统性能参数 2.1 语法 2.2 常用参数 3.统计SQL的查询成本:last_query_cost 4.定位执行慢的SQL:慢查询日志 4.1 慢查询 ...

  7. Sql语句优化之explan分析案例

    ① extra =  Using temporary; Using filesort; sql : EXPLAIN SELECT vtiger_account.accountname, IF(prot ...

  8. mysql执行计划重用_MySQL 优化之EXPLAN执行计划

    MySQL优化之EXPLAN执行计划 ** 备注 ** 本文改编自https://www.processon.com/view/5d4fe8f4e4b04399f5a0303e?fromnew=1#m ...

  9. mysql优化type要到什么程度,mysql优化explan关键字之type

    1. type有哪些? type显示的是访问类型,是较为重要的一个指标,结果值从最好到最差依次是:system>const>eq_ref>ref>range>index& ...

最新文章

  1. 利用MLAI判定未知恶意程序——里面提到ssl恶意加密流检测使用N个payload CNN + 字节分布包长等特征综合判定...
  2. 已知旋转矩阵求角度_如何推导旋转矩阵
  3. boost::geometry::detail::as_range用法的测试程序
  4. linux 显示unix时间,小弟我使用过的Linux命令之uptime - 显示系统运行时间
  5. hdu4932 Miaomiao#39;s Geometry (BestCoder Round #4 枚举)
  6. Python_ collections_defaultdict默认字典
  7. Fragment使用PagerSlidingTabStrip嵌套子Fragment显示问题
  8. GCC如何产生core dump
  9. oracle的nvl和nvl2
  10. Android学习笔记:短信控制手机之“短信开启定位”
  11. Rocketmq介绍和安装
  12. 移除Win10资源管理器中OneDrive图标
  13. 再见!RESTful...
  14. RxJava操作符相关学习资料
  15. java FTP获取文件夹中所有文件
  16. 粒子群在小车机械手臂的应用
  17. Source Insight 常用颜色代表种类
  18. 计算机维修难点,计算机组装与维修习重难点.doc
  19. 总算了解了什么叫云计算
  20. macOS Monterey 12.2 (21D49) 正式版 ISO、IPSW、PKG 下载

热门文章

  1. 如何用手机拍一张证件照(红底、蓝底、白底)?
  2. 元素定位之CSS定位
  3. pdf怎么去除背景水印?实用工具说明
  4. 我38岁被裁,本以为稳进Top3,今天是失业第42天
  5. 无法安装计算机的启动配置,Windows无法更新计算机启动配置 | MOS86
  6. 推荐美文——《念你们的名字》
  7. 【xdoj难题集】 1018 Josephus环的复仇的复仇
  8. 乔布斯的未竟遗愿是iCloud(免费的云服务)
  9. 对话阿里云致凡:社会视频化“狂飙”,倒逼视频云技术加速迭代
  10. java ee是什么_java ee与java的区别是什么