mysql查询优化explain命令详解

Wesley13
• 阅读 696

mysql查询优化的方法有很多种,explain是工作当中用的比较多的一种检查方式。explain翻译即解释,就是看mysql语句的查询解释计划,从解释计划我们能很清楚的看到解释的语句有没有合理用到索引,扫描了多少行数,有没有触及全表扫描、用到临时表等影响慢查询的原因。

使用很简单,如

explain select * from user ...

执行后会出现解释计划的表格,意义可参考下面的参数,针对这些解释计划,我们可以作为相对应的优化。

mysql查询优化explain命令详解

id mysql查询标识符,即序号。

select_type 查询类型

  • simple:即简单select 查询,不包含union及子查询;

  • primary:最外层的 select 查询;

  • union:表示此查询是 union 的第二或随后的查询;

  • dependent union:union 中的第二个或后面的查询语句, 取决于外面的查询;

  • union result:union的结果;

  • subquery:子查询中的第一个select;

  • dependent subquery:子查询中的第一个select,取决于外面的查询,即子查询依赖于外层查询的结果。

table 所有查询到的表。

type 联接类型,比较重要的项,从这一项可以看出是否高效的重要依据

性能从好到坏依次如下:

  • system:表中只有一条数据,这是一个特殊的const 类型;

  • const:针对主键或唯一索引的等值查询扫描,最多只返回一行数据,const 查询速度非常快,因为它仅仅读取一次即可;

  • eq_ref:此类型通常出现在多表的 join 查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果,并且查询的比较操作通常是=, 查询效率较高;

  • ref:此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了 最左前缀 规则索引的查询;

  • fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引;

  • ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多;

  • unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值;

  • index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重;

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

  • range:表示使用索引范围查询,通过索引字段范围获取表中部分数据记录。这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN操作中,此时输出的 ref 字段为 NULL并且key_len字段是此次查询中使用到的索引的最长的那个;

  • index:全表扫描,只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序,但是开销仍然非常大,这种情况时, Extra 字段会显示 Using index;

  • all:性能最差的情况,使用了全表扫描,系统必须避免出现这种情况。

possible_keys 可能用到的索引。

key 真正用到的索引。

key_len 使用了索引字节的长度。

ref 显示索引的哪一列被使用了。

rows 扫描了多少行数,也是性能评估的重要依据。

extra 额度信息,常见的有以下几种。  

  • Distinct:一旦找到了与行相联合匹配的行就不再搜索了;

  • Using filesort:使用了文件排序,性能非常慢,需要优化。

  • Using index:查询使用到了索引,列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候。

  • Using temporary:使用了临时表排序,性能非常慢,需要优化。

  • Using where:表示使用了where进行查询,不是很重要。

  • ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,需要优化。

具体的对执行计划解释可以参考msyql官网:

https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

扩展

另外,mysql5.6增加了对insert/update/delete的explain支持,用法一样。

mysql查询优化explain命令详解

本文分享自微信公众号 - Java技术栈(javastack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
3年前
MySQL——性能优化
性能优化的思路1、首先需要使用慢查询功能,去获取所有查询时间比较长的SQL语句。MySQL——慢查询2、其次使用explain命令去查看有问题的SQL的执行计划。MySQL——执行计划EXPLAIN3、最后可以使用showprofile\s\查看有问题的SQL的性能使用情况。MySQL高级:showprofile
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Explain(MySQL高级知识四)
前言:explain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。explain主要用于分析查询语句或表结构的性能瓶颈。注:本系列随笔如无特殊说明都MySQL版本都为5.7.22。1.explain的作用通过explainsql语句可以知道如下内容:①表的读取顺序。(
Wesley13 Wesley13
3年前
mysql5.6 分页查询优化
mysql5.6分页查询优化场景:表结构:主键(非自增)contentCode(varchar),过滤条件列为updateTime(timeStamp),已经为timestamp建立索引。搜索sql为:SELECTFROMmy_hello_tableWHEREupdat
Wesley13 Wesley13
3年前
SQL语句优化
SQL语句优化规范:1\.使用mysqlexplain对sql执行效率进行检测,explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。1)使用方法:在select语句前加上explain即可2)explain分析结果形式如下:table|type
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究