版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
目录
explain命令通常用来分析低效SQL语句执行慢的原因。explain命令可以获取MySQL执行select语句的指定计划,包括select语句执行过程中表如何连接和连接的顺序。示例:
1、id
id表示执行顺序,数字越大越先执行;在数字大小相等的情况下,从上到下执行。例如在上面的例子中,最先执行的就是最下面那条id = 2的命令。
对于多表关联的情况,一般关联表的id是相同的,但是从上到下第一个表是作为关联主表的。
2、select_type
表示SELECT的类型,常见的取值包括:
- SIMPLE:简单的select查询,查询中不包含子查询和union;
- PRIMARY:查询中包含若干复杂的子部分,最外层查询会被标记为PRIMARY;
- UNION:如果第二个select出现在union之后,则会被标记为UNION;如果UNION包含在FROM子句的子查询中,外层SELECT将被标记为DERIVED;
- UNION RESULT:从UNION表获取结果的SELECT;
- SUBQUERY:在SELECT或者WHERE子句中包含的子查询;
- DERIVED:衍生,在FROM列表中包含的子查询被标记为DERIVED,MySQL会递归这些子查询,把结果放到临时表中。
3、table
指的是输出结果集的表,即这一行子句是在哪个表中获取数据。
4、type
type指的是扫描的类型。mysql5.7中type的类型多达14种,常见的如下几种:
- all:全表扫描;
- index:按照索引的顺序扫描全表,然后再回表读数据。这种情况唯一会比all更快的地方就在于,按照索引扫描是有序的;
- range:有范围的索引扫描,相当于有范围的index类型;
- ref: 查找条件列使用了等号条件,并且使用了非唯一索引;
- ref_eq:扫描唯一索引的ref;
- const:扫描唯一索引,并且该唯一索引列的值为确定的常量。此时MySQL将查询这一部分优化成了一个常量;
- null:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
5、possible_keys、key和key_len
分别表示可能会使用到的索引、实际上使用的索引,以及实际使用的索引列的长度。
6、ref
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。
7、rows
内循环的次数,可以理解为这次查找数据所扫描的行数。
8、Extra
- Using temporary:说明使用了临时表。MySQL的临时表分为in-memory和on-disk两种,优先使用in-memory临时表, 而当临时表太大时,则会被转存为on-disk临时表。临时表一般用来处理比较复杂的排序、去重、分组等查询,或表的关联;
- Using index:索引覆盖查询。覆盖索引指的是可以利用索引返回select需要的全部字段,而不必再次回表读取数据;
- Using where:MySQL服务器会在存储引擎返回行以后,再在服务器中而不是存储引擎中用where进行过滤;
- Using filesort:并不是说一定是通过磁盘文件进行排序,只是说明进行了一个排序操作,区别于使用索引进行排序。这时如果数据量小会在内存中排序(以排序缓冲区为界),如果数据量大则会在文件中排序;
- Using index for group-by:MySQL在特定场景下支持松散索引扫描,例如在一个分组中查询分组的最大值和最小值;
- Using index condition:查找使用了索引,但是需要回表查询数据,以及用WHERE其他的其他条件进行过滤;
- select tables optimized away:优化器从执行计划中移除了该表,并以常数代之,因为MySQL直接从内部表中读到了这个相应的值。查询整列索引列的min()、max()、count()会出现这种提示。