实验环境:
explain_type:
{ EXTENDED | PARTITIONS | FORMAT = format_name}
EXPLAIN与DESCRIBE、DESC是同义词。实践中,通常EXPLAIN用于获取QEP,而DESCRIBE、DESC用于获取表结构信息。
explain_type中,EXTENDED和PARTITIONS 可不写,默认会输出这两列的信息。如:
mysql> explain select * from users where userid=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | users | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
format_name中TRADITIONAL表示输出格式跟上面一样的表格输出,默认此输出格式。JSON表示输出为json格式,如:
mysql> explain format=json select * from users where userid=1\G
*************************** 1. row ***************************
EXPLAIN: {
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "1.00"
},
"table": {
"table_name": "users",
"access_type": "const",
"possible_keys": [
"PRIMARY"
],
"key": "PRIMARY",
"used_key_parts": [
"userid"
],
"key_length": "8",
"ref": [
"const"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 1,
"filtered": "100.00",
"cost_info": {
"read_cost": "0.00",
"eval_cost": "0.20",
"prefix_cost": "0.00",
"data_read_per_join": "2K"
},
"used_columns": [
"userid",
"alias",
"name",
"surname",
"passwd",
"url",
"autologin",
"autologout",
"lang",
"refresh",
"type",
"theme",
"attempt_failed",
"attempt_ip",
"attempt_clock",
"rows_per_page"
]
}
}
}
1 row in set, 1 warning (0.00 sec)
除SELECT语句外,EXPLAIN还可直接获取DELETE/UPDATE/INSERT/REPLACE语句的QEP而无需改写为SELECT语句。如:
mysql> explain delete from users where userid=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | DELETE | users | NULL | range | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set (0.00 sec)
mysql> explain update users set name='test' where userid=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | UPDATE | users | NULL | range | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set (0.00 sec)
mysql> explain insert into usrgrp values(1,'test',0,0,0);
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | INSERT | usrgrp | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set (0.00 sec)
mysql> explain replace into usrgrp values(1,'test',0,0,0);
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | REPLACE | usrgrp | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set (0.00 sec)
输出
输出列 | 含义 |
---|---|
id | 查询标识 |
select_type | 查询类型 |
table | 查询涉及的表 |
partitions | 匹配到的分区信息 |
type | 连接类型 |
possible_keys | 可能选择的索引 |
key | 实际使用的索引 |
key_len | 实际使用的索引的长度 |
ref | 和索引进行比较的列 |
rows | 需要被检索的大致行数 |
filtered | 按表条件过滤的行百分比 |
Extra | 额外信息 |
id:
查询标识,查询语句的序号。
表示查询中执行select子句或操作表的顺序
id相同,执行顺序由上至下:
mysql> explain select * from users t1,users_groups t2 where t1.userid = t2.userid;
+----+-------------+-------+------------+------+----------------+----------------+---------+------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+----------------+----------------+---------+------------------+------+----------+-------+
| 1 | SIMPLE | t1 | NULL | ALL | PRIMARY | NULL | NULL | NULL | 7 | 100.00 | NULL |
| 1 | SIMPLE | t2 | NULL | ref | users_groups_2 | users_groups_2 | 8 | zabbix.t1.userid | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+----------------+----------------+---------+------------------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行:
mysql> explain select * from users where userid = (select userid from users_groups where id=4);
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | PRIMARY | users | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |
| 2 | SUBQUERY | users_groups | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行:
mysql> explain select * from users where userid in (select userid from users_groups);
+----+--------------+--------------+------------+--------+----------------+----------------+---------+---------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+--------------+------------+--------+----------------+----------------+---------+---------------------+------+----------+-------------+
| 1 | SIMPLE | users | NULL | ALL | PRIMARY | NULL | NULL | NULL | 7 | 100.00 | Using where |
| 1 | SIMPLE | | NULL | eq_ref | key> | _key> | 8 | zabbix.users.userid | 1 | 100.00 | NULL |
| 2 | MATERIALIZED | users_ groups | NULL | index | users_groups_2 | users_groups_2 | 8 | NULL | 7 | 100.00 | Using index |
+----+--------------+--------------+------------+--------+----------------+----------------+---------+---------------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)
当该行数据引用了其它查询的UNION结果时,id列显示为NULL,此时,table列显示类似这样:< unionM,N>,表示引用了查询标识为M、N的两行的UNION结果。如:
mysql> explain select userid from users where userid=1 union select usrgrpid userid from usrgrp where usrgrpid=7;
+----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+
| 1 | PRIMARY | users | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index |
| 2 | UNION | usrgrp | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | Using index |
| NULL | UNION RESULT | | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)
select_type
查询类型。
查询类型 | 含义 |
---|---|
SIMPLE | 简单查询(不包含子查询或UNION) |
PRIMARY | 最外层查询 |
UNION | UNION语句中第二或更后面的查询 |
DEPENDENT UNION | 依赖外部查询的UNION中第二或更后面的查询 |
UNION RESULT | UNION语句的结果集 |
SUBQUERY | 子查询中的第一个查询 |
DEPENDENT SUBQUERY | 依赖外部查询的子查询中的第一个查询 |
DERIVED | 查询的派生表(在FROM从句中的子查询) |
MATERIALIZED | 物化子查询 |
UNCACHEABLE SUBQUERY | 无法缓存结果的子查询,并且必须为外部查询的每一行重新计算 |
UNCACHEABLE UNION | 属于无法缓存的子查询的UNION的第二或更后面的查询 |
table
输出行引用的表的名称。这也可以是下列值之一:
< unionM,N>:输出行引用了id值为M和N的行的UNION结果。
< derivedN>:该行引用了一个id值为n的行的派生表结果。
例如,派生表可以从from子句的子查询中得到结果。
< subqueryN>:输出行引用了id值为N的行的物化子查询的结果
partitions
由查询匹配记录的分区。对于非分区表,值为NULL。
type
表示MySQL在表中找到所需行的方式,又称“访问类型”,常见类型从最好到最差依次如下:
system, const, eq_ref, ref, fulltext, ref_or_null, index_merge, unique_subquery, index_subquery, range, index, ALL
system
表只有一行记录,这是const类型的一种特殊情况。
mysql> explain select * from mysql.proxies_priv;
+----+-------------+--------------+------------+--------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------+------------+--------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | proxies_priv | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+--------------+------------+--------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
const
常量查询。
在整个查询过程中,该表最多有一个匹配行,在查询开始时读取。
因为只有一行,所以这个行中的列值可以被其他优化器视为常量。const表非常快,因为它们只读一次。
当你将主键或唯一索引的所有部分与常量值进行比较时,将使用const。
例如:
mysql> explain select * from users where userid=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | users | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
eq_ref
对前面的表中每一行记录的组合,都从当前表中读取一行。
除了system和const类型之外,这是最好的连接类型。
主键或非空唯一索引在索引的所有部分都被join使用时采用。
eq_ref可用于与使用=操作符进行比较的索引列。
比较值可以是一个常量,也可以是一个在该表之前读取的表的列的表达式。
类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。
mysql> explain select * from users_groups a ,usrgrp b where a.id = b.usrgrpid;
+----+-------------+-------+------------+--------+---------------+----------------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+----------------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | a | NULL | index | PRIMARY | users_groups_1 | 16 | NULL | 7 | 100.00 | Using index |
| 1 | SIMPLE | b | NULL | eq_ref | PRIMARY | PRIMARY | 8 | zabbix.a.id | 1 | 100.00 | NULL |
+----+-------------+-------+------------+--------+---------------+----------------+---------+-------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
ref
对前面的表中每一行记录的组合,都从当前表中读取所有匹配索引值的行。
如果join仅使用key的最左前缀,或者key不是主键或唯一索引(换句话说,如果连接不能基于key值选择单个行),则使用ref。
如果使用的key只匹配几行,这是一个很好的连接类型。
简单来说,就是使用非唯一索引扫描或者唯一索引的前缀扫描,返回匹配某个单独值的记录行
mysql> explain select * from media a,media_type b where a.mediatypeid=b.mediatypeid and b.mediatypeid=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | b | NULL | const | PRIMARY | PRIMARY | 8 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | a | NULL | ref | media_2 | media_2 | 8 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
fulltext
连接是使用全文索引执行的。
ref_or_null
这个连接类型就像ref,但是加上MySQL对包含空值的行进行了额外的搜索。
这种连接类型优化通常用于解决子查询。
例如:
mysql> explain select * from graphs where templateid=1 or templateid is null;
+----+-------------+--------+------------+-------------+---------------+----------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------------+---------------+----------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | graphs | NULL | ref_or_null | graphs_2 | graphs_2 | 9 | const | 2523 | 100.00 | Using index condition |
+----+-------------+--------+------------+-------------+---------------+----------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
index_merge
此连接类型指示使用索引合并优化。
在此情形下,输出行中的key列包含所使用的索引列表,key_len列包含用于所使用索引的最长key部分的列表。
unique_subquery
该类型在某些如下格式的IN子查询中替代eq_ref:
value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery只是一个索引查找函数,它完全替代了子查询以提高效率。
index_subquery
该类型与unique_subquery很相似。它也是替代IN子查询,但它适用如下格式的子查询中的非唯一索引:
value IN (SELECT key_column FROM single_table WHERE some_expr)
range
只有在给定范围内的行被检索,才使用索引来选择行。
输出行中的key列指示使用哪个索引。
key_len包含所使用的最长key部分。
此类型的ref列为NULL。
range用于当一个key列与一个常量使用=,<>,>,>=,<,<=,<=>,BETWEEN,或IN()操作符进行比较时.
mysql> explain select * from media where mediatypeid >4;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | media | NULL | range | media_2 | media_2 | 8 | NULL | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
index
索引连接类型与ALL相同,只是扫描索引树。有两种情况:
一个全表扫描以索引顺序读取索引来查找数据行。Extra列不显示Using index
按索引次序扫描,先读索引,再读实际的行,结果还是全表扫描,主要优点是避免了排序。因为索引是排好的
当查询仅使用单个索引的一部分的列时,MySQL可以使用此连接类型。
mysql> explain select source from problem ;
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | problem | NULL | index | NULL | problem_1 | 16 | NULL | 32629 | 100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
ALL
全表扫描。
通常情况下,如果表是第一个未标记为const的表,并且在所有其他情况下通常都非常糟糕,那么这通常是不好的。
通常情况下,您可以通过添加索引来避免所有的问题,这些索引可以根据前面的表中的常量值或列值来从表中进行行检索。
mysql> explain select * from problem ;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| 1 | SIMPLE | problem | NULL | ALL | NULL | NULL | NULL | NULL | 32629 | 100.00 | NULL |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
1 row in set, 1 warning (0.00 sec)
possible_keys
该列指示了MySQL查找表中的行时可以选择的索引。
注意,这个列完全独立于来自EXPLAIN的输出中显示的表的顺序。
这意味着,可能在使用生成的表顺序时,一些可能的键可能无法使用。
如果该列为空,则没有相关的索引。在这种情况下,您可以通过检查WHERE子句来检查是否引用了适合于索引的某些列或列,从而提高查询的性能。如果是这样,创建一个适当的索引并再次检查查询。
key
显示MySQL在查询中实际决定使用的索引,若没有使用索引,显示为NULL
key_len
key_len列表示MySQL决定使用的键的长度(字节数)。
key_len的值使您能够确定MySQL实际使用了一个多列索引的哪些部分。
如果key列表示为NULL,key_len列也表示为NULL。
由于key的存储格式,对于一个可以为空的列,key长度比非空列更大。
key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
ref
ref列显示哪些列或常量与键列中命名的索引相比较,以从表中选择行。
如果值是func,则使用的值是某个函数的结果。要查看是哪个函数,请在EXPLAIN后使用SHOW WARNINGS来查看EXPLAIN的扩展输出。这个函数实际上可能是一个运算符,例如算术运算符。
rows
表示MySQL认为执行该查询必须检查的行数。这是根据表统计信息及索引选用情况得出地结果。
对于InnoDB表,这个数字是一个估计值,可能并不总是准确的。
filtered
该列表示将被表条件过滤的表行的估计百分比。
即rows显示了估计的检查行数, rows*filtered/100 显示与前面的表做join的行数。
Extra
该列包含MySQL如何处理查询的附加信息。
1.Using index
该值表示相应的select操作中使用了覆盖索引(Covering Index)
覆盖索引(Covering Index)
MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件
包含所有满足查询需要的数据的索引称为覆盖索引(Covering Index)
注意:如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可select *,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降。
mysql> explain select source from problem ;
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | problem | NULL | index | NULL | problem_1 | 16 | NULL | 32629 | 100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-----------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
2.Using where
表示mysql服务器将在存储引擎检索行后再进行过滤。许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where字句的查询都会显示”Using where”。有时”Using where”的出现就是一个暗示:查询可受益于不同的索引。
mysql> explain select * from users where name='Zabbix';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 7 | 14.29 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
3.Using temporary
表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
这个值表示使用了内部临时(基于内存的)表。一个查询可能用到多个临时表。有很多原因都会导致MySQL在执行查询期间创建临时表。两个常见的原因是在来自不同表的上使用了DISTINCT,或者使用了不同的ORDER BY和GROUP BY列。可以强制指定一个临时表使用基于磁盘的MyISAM存储引擎。这样做的原因主要有两个:
1)内部临时表占用的空间超过min(tmp_table_size,max_heap_table_size)系统变量的限制
2)使用了TEXT/BLOB 列
mysql> explain select * from trends_uint where itemid in (select itemid from trends order by clock) order by itemid;
+----+-------------+-------------+------------+-------+---------------+---------+---------+----------------------+----------+----------+---------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+-------+---------------+---------+---------+----------------------+----------+----------+---------------------------------------------------------+
| 1 | SIMPLE | trends | NULL | index | PRIMARY | PRIMARY | 12 | NULL | 18369191 | 0.38 | Using index; Using temporary; Using filesort; LooseScan |
| 1 | SIMPLE | trends_uint | NULL | ref | PRIMARY | PRIMARY | 8 | zabbix.trends.itemid | 270 | 100.00 | NULL |
+----+-------------+-------------+------------+-------+---------------+---------+---------+----------------------+----------+----------+---------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
4.Using filesort
MySQL中无法利用索引完成的排序操作称为“文件排序”
mysql> explain select * from trends_uint order by num;
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------+
| 1 | SIMPLE | trends_uint | NULL | ALL | NULL | NULL | NULL | NULL | 30427219 | 100.00 | Using filesort |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------+
1 row in set, 1 warning (0.01 sec)
5.Using join buffer
该值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
mysql> explain select * from (select * from media_type) a ,media b where a.mediatypeid=b.mediatypeid;
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| 1 | SIMPLE | media_type | NULL | ALL | PRIMARY | NULL | NULL | NULL | 4 | 100.00 | NULL |
| 1 | SIMPLE | b | NULL | ALL | media_2 | NULL | NULL | NULL | 5 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
6.Impossible where
这个值强调了where语句会导致没有符合条件的行。
mysql> explain select * from trends_uint where 1=2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.00 sec)
7.Select tables optimized away
这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行.
8.Index merges
当MySQL 决定要在一个给定的表上使用超过一个索引的时候,就会出现以下格式中的一个,详细说明使用的索引以及合并的类型。
Using sort_union(…)
Using union(…)
Using intersect(…)
参考:https://www.cnblogs.com/gomysql/p/3720123.html
参考:https://www.cnblogs.com/xiaoboluo768/p/5400990.html
参考:https://blog.csdn.net/b1303110335/article/details/51174540