必备技巧-mysql中explain用法详解

做一个积极的人
编码、改bug、提升自己

我有一个乐园,面向编程,春暖花开!


“ explain 查询和分析SQl的执行记录,可以进行sql的性能优化!”

昨日分享了必看,Mysql索引核心知识汇总 有一些伙伴想了解一下explain的用法,这里做一下简单介绍。

                                       

explain用法


   
   
  1. mysql> explain select * from students;

  2. +----+-------------+----------+------+---------------+------+---------+------+------+-------+

  3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

  4. +----+-------------+----------+------+---------------+------+---------+------+------+-------+

  5. | 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 3 | |

  6. +----+-------------+----------+------+---------------+------+---------+------+------+-------+

  7. 1 row in set

  8. mysql> explain extended select * from students;

  9. +----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+

  10. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

  11. +----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+

  12. | 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 3 | 100 | |

  13. +----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+

  14. 1 row in set

注: 用explain extended查看执行计划会比explain多一列 filtered。

filtered列给出了一个百分比的值,这个百分比值和rows列的值一起使用,可以估计出那些将要和explain中的前一个表进行连接的行的数目。

explain结果字段的含义介绍

id
  • SELECT识别符。这是SELECT的查询序列号,表示查询中执行select子句或操作表的

    顺序!

select_type

SELECT类型,可以为以下任何一种:

  • SIMPLE:简单SELECT(不使用UNION或子查询)

  • PRIMARY:最外面的SELECT

  • UNION:UNION中的第二个或后面的SELECT语句

  • DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询

  • UNION RESULT:UNION 的结果

  • SUBQUERY:子查询中的第一个SELECT

  • DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

  • DERIVED:导出表的SELECT(FROM子句的子查询)

table

输出的行所引用的表!

type

联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:

  • system:表仅有一行(=系统表)。这是const联接类型的一个特例。

  • const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!

  • eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。

  • ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。

  • refornull:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。

  • index_merge:该联接类型表示使用了索引合并优化方法。

  • uniquesubquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primarykey FROM singletable WHERE someexpr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

  • indexsubquery:该联接类型类似于uniquesubquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT keycolumn FROM singletable WHERE some_expr)

  • range:只检索给定范围的行,使用一个索引来选择行。

  • index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

  • ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。

possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

key

显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(keylen显示的值为索引字段的最大可能长度,并非实际使用长度,即keylen是根据表定义计算而得,不是通过表内检索出的)

ref

表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数

filtered

显示了通过条件过滤出的行数的百分比估计值。

Extra

该列包含MySQL解决查询的详细信息

  • Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。

  • Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。

  • Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。

  • Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。

  • Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。

  • Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。

  • Using sortunion(...), Using union(...), Using intersect(...):这些函数说明如何为indexmerge联接类型合并索引扫描。

  • Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

explain使用实例


   
   
  1. mysql> show keys from students; // 查询索引,创建了一个 index_create_date 索引

  2. +----------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

  3. | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |

  4. +----------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

  5. | students | 0 | PRIMARY | 1 | stud_id | A | 3 | NULL | NULL | | BTREE | | |

  6. | students | 1 | index_create_date | 1 | create_date | A | 3 | NULL | NULL | YES | BTREE | | |

  7. +----------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

  8. 2 rows in set

  9. mysql> explain select * from students where stud_id = '1'; // 使用主键查询

  10. +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+

  11. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

  12. +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+

  13. | 1 | SIMPLE | students | const | PRIMARY | PRIMARY | 4 | const | 1 | |

  14. +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+

  15. 1 row in set

  16. mysql> explain select * from students where create_date = '2010-01-01'; // 使用索引查询

  17. +----+-------------+----------+------+-------------------+-------------------+---------+-------+------+-------------+

  18. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

  19. +----+-------------+----------+------+-------------------+-------------------+---------+-------+------+-------------+

  20. | 1 | SIMPLE | students | ref | index_create_date | index_create_date | 4 | const | 1 | Using where |

  21. +----+-------------+----------+------+-------------------+-------------------+---------+-------+------+-------------+

  22. 1 row in set

总结

  • EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况

  • EXPLAIN不考虑各种Cache

  • EXPLAIN不能显示MySQL在执行查询时所作的优化工作

  • 部分统计信息是估算的,并非精确值

  • EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

参考博文

EXPLAIN 命令详解

1. 全栈架构之打包推荐【建议收藏,常读】

2. 探讨确保消息消费幂等性的几种方式

3. 分布式系统中Session共享的常用方案

4. Java语言中的生僻知识

5. 我是一个Java类(附带精彩吐槽)

6. mysql索引失效,差点我的工作凉了

7. 既生synchronized,何生volatile?

8. 微服务一直火,为什么服务化要搞懂?

9. MySQL的COUNT语句,不简单!

10. 漫画:HashSet和TreeSet实现与原理

扫码二维码关注我

·end·

—如果本文有帮助,请分享到朋友圈吧—

我们一起愉快的玩耍!

你点的每个赞,我都认真当成了喜欢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值