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