SQL优化之EXPLAIN基本介绍

在执行数据库查询稍慢时,可以执行EXPLAIN + 查询语句来查看此sql语句的具体执行方式:


id:select识别符,表示查询中执行select子句或操作表的顺序
select_type:查询的类型

  • SIMPLE:简单的查询,语句中不包含子查询和UNION;
  • PRIMARY:语句中包含子查询,标记外层语句;
  • UNION:若第二个select出现在UNION之后,则被标记为UNION,若UNION包含在from子句的子查询中,外层select将被标记为:DERIVED;
  • DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询;
  • UNION RESULT:从UNION表(即UNION合并的结果集)中获取select查询的结果;
  • SUBQUERY:子查询中的第一个select;
  • DEPENDENT SUBQUERY:子查询中的第一个select,取决于外面的查询;
  • DERIVED:在from列表中包含的子查询被标记为DERIVED(衍生表),mysql会递归执行这些子查询,把结果放临时表中;
  • MATERIALIZED:物化子查询;
    10.UNCACHEABLE SUBQUERY:无法缓存结果的子查询,必须为外部查询的每一行重新评估该子查询;
    11.UNCACHEABLE UNION:属于非可缓存子查询的联合中的第二个或更晚的选择(参见非可缓存子查询);
    table:表名
    partitions:代表分区表中的命中情况,非分区表,该项为null
    type:查询方式
    从好到差依次为:system,const,eq_ref,ref,fulltext,ref_or_null,index_merge,unique_subquery,index_subquery,range,index,ALL。
  • system:The table has only one row (= system table)表中只有一行数据或者是空表
  • const:使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描
  • eq_ref:出现在连表语句中,驱动表的连接字段是逐渐或唯一性索引,且必须为not null,唯一索引和主键是多列时,只有所有的列都用作比较时才会出现eq_ref
  • ref:ref没有eq_ref严格,没有要求连接表的顺序,也不要求包含主键或唯一性索引,常见与普通索引的连表中
  • fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
  • ref_or_null:与ref方法类似,只是增加了null值的比较。实际用的不多
  • index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取所有索引,性能可能大部分时间都不如range
  • unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值
  • index_subquery:用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重
  • range:索引范围扫描,常见于使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN()或者like等运算符的查询中
  • index:索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询
  • ALL:这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录

possible_keys:指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个

key_len:key_len说明MySQL会用到的索引长度,单列索引用到整个索引的长度,index_merge中算出具体用到的索引长度,该字段只会算where条件用用到索引,order by和group by不在统计范围内。

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

rows:这里是执行计划中估算的扫描行数,不是精确值。

filtered:5.7之后的版本默认就有这个字段,不需要使用explain extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。

extra:查询计划器给出额外的信息说明。

  1. Using filesort(出现这个东西不好):说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,mysql中无法利用索引完成的排序操作称为"文件排序"。
  2. Using temporary(出现这个东西更不好,使用到了临时表):使用了临时表保存中间结果,Mysql在对查询结果排序时使用临时表,常见于排序order by和分组查询group by。
  3. Using index:表示相应的select操作中使用了覆盖索引(Covering Index),避免了访问了表的数据行,效率不错。
  4. Using where:使用了where。
  5. Using join buffer:使用了链接缓存。
  6. Impossible where:where 子句的值总是false,不能用来获取任何元素。
  7. Select tables optimized away:在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化count(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
  8. Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
  9. Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。

你可能感兴趣的:(#,MySQL)