欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SQL优化之EXPLAIN基本介绍

程序员文章站 2022-04-20 21:46:29
...
在执行数据库查询稍慢时,可以执行EXPLAIN + 查询语句来查看此sql语句的具体执行方式:

SQL优化之EXPLAIN基本介绍
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标准的行后,不再为前面的的行组合在该表内检查更多的行。