MySQL执行计划Explain详解

数据库 MySQL
使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。分析你的查询语句或是表结构的性能瓶颈

什么是执行计划

使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。分析你的查询语句或是表结构的性能瓶颈

执行计划的作用

  1. 表的读取顺序
  2. 数据读取操作的操作类型
  3. 哪些索引可以使用
  4. 哪些索引被实际使用
  5. 表之间的引用
  6. 每张表有多少行被优化器查询

执行计划的语法

执行计划的语法其实非常简单:在SQL 查询的前面加上 EXPLAIN 关键字就行。

EXPLAIN select * from table1

重点的就是 EXPLAIN 后面你要分析的 SQL 语句

执行计划详解

通过 EXPLAIN 关键分析的结果由以下列组成,接下来挨个分析每一个列

一、ID 列

ID 列:描述 select 查询的序列号,包含一组数字,表示查询中执行 select 子句或操作表的顺序

根据 ID 的数值结果可以分成以下三种情况

  • id 相同:执行顺序由上至下
  • id 不同:如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行
  • id 相同又不同:同时存在

分别举例来看

Id 相同

如上图所示,ID 列的值全为 1,代表执行的允许从 t1 开始加载,依次为 t3 与 t2

EXPLAIN
select t2.* from t1,t2,t3 where t1.id = t2.id and t1.id = t3.id
and t1.other_column = '';

Id 不同

如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行

EXPLAIN
select t2.* from t2 where id = (
select id from t1 where id = (select t3.id from t3 where t3.other_column='')
);

Id 相同又不同

id 如果相同,可以认为是一组,从上往下顺序执行;

在所有组中,id 值越大,优先级越高,越先执行

EXPLAIN
select t2.* from (
select t3.id
from t3 where t3.other_column = ''
) s1 ,t2 where s1.id = t2.id

二、select_type 列

Select_type:查询的类型,

要是用于区别:普通查询、联合查询、子查询等的复杂查询

类型如下

三、table 列

显示这一行的数据是关于哪张表的

四、Type 列

type 显示的是访问类型,是较为重要的一个指标,结果值从最好到最坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery >

index_subquery > range > index > ALL

需要记忆的:system>const>eq_ref>ref>range>index>ALL

一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

System 与 const

System:表只有一行记录(等于系统表),这是 const 类型的特例,平时不会出现,这个也可以忽略不计

Const:表示通过索引一次就找到了。const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快如将主键置于 where 列表中,MySQL 就能将该查询转换为一个常量

eq_ref

唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描

Ref

非唯一性索引扫描,返回匹配某个单独值的所有行。

本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体

Range

只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引一般就是在你的 where 语句中出现了 between、<、>、in 等的查询这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。

Index

当查询的结果全为索引列的时候,虽然也是全部扫描,但是只查询的索引库,而没有去查询

数据

All

Full Table Scan,将遍历全表以找到匹配的行

五、possible_keys 与 Key列

possible_keys:可能使用的 key

Key:实际使用的索引。如果为 NULL,则没有使用索引

查询中若使用了覆盖索引,则该索引和查询的 select 字段重叠

EXPLAIN select col1,col2 from t1

其中 key 和 possible_keys 都可以出现 null 的情况(结婚邀请朋友的例子)

六、key_len列

desc
select * from ta where col1 ='ab';
desc
select * from ta where col1 ='ab' and col2 = 'ac'

Key_len 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精

确性的情况下,长度越短越好

key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的

  • key_len 表示索引使用的字节数,
  • 根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断所有的索引字段是否都被查询用到。
  • char 和 varchar 跟字符编码也有密切的联系,
  • latin1 占用 1 个字节,gbk 占用 2 个字节,utf8 占用 3 个字节。(不同字符编码占用的
  • 存储空间不同)

七、Ref列

显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值

EXPLAIN
select * from s1 ,s2 where s1.id = s2.id and s1.name = 'enjoy'

由 key_len 可知 t1 表的 idx_col1_col2 被充分使用,col1 匹配 t2 表的 col1,col2 匹配了一个常量,即 'ac'其中 【shared.t2.col1】 为 【数据库.表.列】

八、Rows

根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数

九、Extra

包含不适合在其他列中显示但十分重要的额外信息。


责任编辑:武晓燕 来源: 今日头条
相关推荐

2021-02-20 08:40:19

HiveExplain底层

2021-03-17 09:35:51

MySQL数据库explain

2022-02-15 07:36:21

SQLEXPLAIN数据库

2021-05-28 10:46:36

MySQL执行计划

2022-08-08 08:03:44

MySQL数据库CBO

2011-09-14 17:03:17

数据库执行计划解析

2020-05-21 10:02:51

Explain SQL优化

2020-09-15 08:44:57

MySQL慢日志SQL

2021-04-24 12:01:08

MySQL数据库Mysql执行计划

2017-07-27 20:00:47

MySQLEXPLAIN命令

2015-04-22 14:17:45

SQL SERVERMSSQL SERVE缓冲区

2018-02-27 14:00:35

数据库MySQL统计信息

2017-11-15 08:50:59

数据库MySQL

2009-11-13 16:28:02

Oracle生成执行计

2010-04-16 09:27:18

Ocacle执行计划

2022-08-15 15:09:26

SQL数据库MySQL

2009-11-18 17:05:47

捕获Oracle SQ

2009-11-10 16:00:05

Oracle执行计划

2021-09-07 10:43:25

EverDB分布式执行

2021-11-09 07:59:50

开发
点赞
收藏

51CTO技术栈公众号