mysql explain 使用_MySQL explain使用

1.介绍

EXPLAIN 命令用于SQL语句的查询执行计划。这条命令的输出结果能够让我们了解MySQL 优化器(optimlzer)是如何执行SQL 语句的。这条命令并没有提供任何调整建议,但它能够提供重要的信息帮助你做出调优决策。

下面执行连接查询语句

explain select * from goods_goods inner join goods_goodscategory on goods_goods.category_id = goods_goodscategory.id;

4545ce5ea343079f65cdc995847df368.png

接下来我们来逐一分析该结果各字段(id、 select,、table、 partitions、possible_keys、key、key_len、ref、rows、filtered、extra)含义

为测试准备两张表:

9a966537b5ea954a14bce056a16bed5c.png

2. explain之id

id表示了DML中所涉及表的查询顺序,值越大表示越先执行,值相同时,从上至下执行

explain select * from goods_goods g where g.id = (select distinct category_id from goods_goodscategory where id=100);

742e4bbf27e47381e7f423333c7152f8.png

3. explain之select_type

select_type 列提供了 对表的查询类型。最常见的值包括SIMPLE、PRIMARY、DERIVED 和UNION。其他可能的值还有 UNION RESULT、SUBQUERY 等等.

SIMPLE:

不包含子查询和其他复杂语法的简单查询,(包含join)

0bb9e6a3002df8620ec369afa242f672.png

PRIMARY:

在存在子查询的语句中,最外面的select查询就是primary

explain select * from goods_goods g where g.id = (select distinct category_id from goods_goodscategory where id=100);

742e4bbf27e47381e7f423333c7152f8.png

SUBQUERY:

在select或where列表中包含了子查询

DERIVED:

在from列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,并把结果放在临时表中。

explain select id from (select * from goods_goods where id<10);

错误:

f73bddc038baf40f53a7e29ae1e7c15f.png

为from后的表取别名后才能执行正确,该处的from子句后的表就是一个临时表

explain select id from (select * from goods_goods where id<10) as new_table;

UNION:

第二个select出现union之后,则被标记为union,若union包含在from子句的子查询中,外层select被标记为derived;

explain select * from (select 1 as A union select 2 as B) as newt;

9f8dc178a0c866da16750c7cb1fe841f.png

UNION RESULT:

从union表中获取结果的select

4. explain之type

type所涉及的值主要有如下几种取值:

最好----->最差

system

const

eq_ref

ref

range

index

all

全部值集有:

最好----->最差

system

const

eq_ref

ref

fulltext

ref_or_null

index_merge

unique_subquery

index_subquery

range

index

all

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

system:

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

const:

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

explain select * from (select * from goods_goods where id = 1) nt;

b963d901e81288cbbbcab4066646a92a.png

内层的select为const,通过主键只匹配了一行数据,其结果作为临时表交由外层select查询,所以外层的select查询的type就是system,因为临时表只有一行数据。

eq_ref:

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

962adbc5ea51122d7ead912082744bed.png

explain select * from ref_student s, ref_major m where s.major=m.id;

bb571d2790d692c48ff79d65241083e1.png

注意:如果此时ref_student中存在多条记录,则该TYPE就是ALL了,如果ref_student中只有一条记录,但ref_major有多条记录,则还是EQ_REF类型

意思就是说,主表与从表通过外键A关联,在主表中可能存在多条记录,但从表的记录只有一条

ref:

出现该连接类型的条件是: 查找条件列使用了索引而且不为主键和unique。其实,意思就是虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描。但它的好处是它并不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内扫描。下面为了演示这种情形,给employee表中的name列添加一个普通的key(值允许重复)

alter table mstudent add key idx_name(name); #为name字段添加非唯一性索引

e0df4ed85996383e28e4984c12e2dbeb.png

cfed229ad2b001e8dd2b30520a5ea9d6.png

range:

范围查找,例如在where子句后添加条件范围(IN、BETWEEN、>、

index:

基于索引进行全表扫描

809d9a24aac056cfaf21ac8a55053794.png

5. explain之type、key、key_len、rows、ref等

possible_keys:

显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引项被列出,但不一定被查询实际使用。

key:

实际使用的索引,若为null,则没有使用到索引。(两种可能,①没建立索引。②建立索引,但索引失效)。查询中若使用了覆盖索引,则该索引仅出现在key列表中。

key_len:

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确型的情况下,长度越短越好,key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据定义计算而得,不是通过表内检索出的。

rows:

每张表有多少行被mysql优化器查询

ref:

引用到的上一个表的列,

6. explain之extra

包含不适合在其他列中显示,但又十分重要的信息,其主要取值参数如下:

using filesort:

当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序。Explain不会显示的告诉客户端用哪种排序。官方解释:“MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行”

1267f7ebd22922c291002fbd2b681cf4.png

dce8ffeb67434a6f47bda6b4c3fe1e4d.png

前者使用了额外的排序,后者使用自建的索引排序,后者性能优于前者

using temporary:

使用了临时表保存了中间结果,MySQL在对结果排序时使用了临时表,常见于group by和order by;

group by后尽量基于where子句后的索引来进行分组

using index:

覆盖索引:select数据列只用从索引中就能取得,不必读取数据行。

表示相应select操作中使用了覆盖索引,避免了访问表的数据行,效率高,

如果同时出现using where,表明索引被用来执行索引键值的查找

如果没有同事出现using where,表明索引用来读取数据而非执行查找动作

48e36a7a7244fd39c3840352d6c73c4a.png

impossible where:

where子句后的条件逻辑错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值