我们常常用到 explain
这个命令查看一些 SQL 语句的查询计划,查看 SQL 语句是否使用上了索引、有没有做全表扫描,这些都可以使用 explain
命令来查看。
1 | mysql> explain select * from servers; |
使用 explain
命令查询出来的信息有10列,分别是id
,select_type
,table
,type
,possible_keys
,key
,key_len
,ref
,rows
,Extra
。下面对这些字段做出解释。
一、id
SELECT
识别符,是 SELECT
的查询序列号。
- id 相同时,执行顺序由上至下。
- 如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行
- id 如果相同,可以认为是一组,从上往下执行;在所有组中,id 值越大,优先级越高,越先被执行。
二、select_type
表示查询中每个 SELECT
子句的类型
- SIMPLE(简单使用 SELECT,不使用 UNION 或者子查询)
- PRIMARY(查询中若包含子查询,则最外层的 SELECT 被标记为 PRIMARY)
- UNION(UNION 中第二个或者后面的 SELECT)
- DEPENDENT UNION(UNION中的第二个或者后面的查询依赖于外面的查询)
- UNION RESULT(UNION 的查询结果)
- SUBQUERY(子查询中的第一个 SELECT)
- DEPENDENT SUBQUERY(子查询中的第一个 SELECT,取决于外面的查询)
- DERIVED(派生表中的 SELECT,FROM 子句的子查询)
- UNCACHEABLE(子查询的结果不能被缓存,必须重新评估外连接的第一行)
三、table
显示这一行的数据是属于哪张表的,有时显示的不是真实的表名,比如 derive2
。
1 | mysql> explain select * from (select * from ( select * from t1 where id=2602) a) b; |
四、type
表示 MySQL 在表中找到所需行的方式,又称“访问类型”
常用的类型有:ALL,index,range,ref,eq_ref,const,system,NULL(从左到右,性能从差到优)
- ALL:Full Table Scan,MySQl 将遍历全表以找到匹配的行
- index:Full Index Scan,index 与 All 类型的区别为 index 类型只遍历索引树。
- range:只检索给定范围的行,使用一个索引来选择行。
- ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
- eq_ref:类似 ref,区别就在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用 primary key 或者 unique key 作为关联条件
- const、system:当 MySQL 对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。比如将主键置于
where
列表中,MySQL 就能将该查询转换为一个常量,system 是 const 类型的特例,当查询的表只有一行的情况下,使用 system。 - NULL:MySQl 在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
五、possible_keys
指出 MySQL能使用哪些索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被引出,但不一定被查询使用。
该列完全独立于 explain 输出所示的表的次序。这意味着 possible_keys 中的某些键实际上不能按生成的表的次序使用。
如果该列是 NULL,则没有相关的索引。在这种情况下,可以通过检查 where
子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用 explain 检查查询。
六、key
key 列显示 MySQL 实际决定使用的索引
如果没有选择索引,则键是 NULL。要想强制 MySQL 使用或忽略 possible_keys 列中的索引,在查询中使用 FORCE INDEX、USE INDEX 或者 IGNORE INDEX。
七、key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。
八、ref
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
九、rows
表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数(扫描多少行)
十、Extra
该列包含MySQL解决查询的详细信息,有以下几种情况:
- Using where
- Using temporary
- Using filesort
- Using join buffer
- Impossible where
- Select tables optimized away
十一、filtered
显示了通过条件过滤出的行数的百分比估计值。
十二、partitions
匹配的分区
总结:
- EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
- EXPLAIN不考虑各种Cache
- EXPLAIN不能显示MySQL在执行查询时所作的优化工作
- 部分统计信息是估算的,并非精确值
- EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。