explain各个参数的状态及含义


explain 有以下字段:

id:本次连接的标识符
select_type:查询的类型,主要有以下几种。
depednet subquery :子查询中的第一个select依赖于外部的查询。
primary: 最外层的 select。
mysql> explain select uid from testusers where uid in (select uid from testusers where uid=5);
+----+--------------------+-----------+--------+---------------+---------+---------+------+------+--------------------------+
| id | select_type        | table     | type   | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+--------------------+-----------+--------+---------------+---------+---------+------+------+--------------------------+
|  1 | PRIMARY            | testusers | index  | NULL          | PRIMARY | 4       | NULL |    2 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | testusers | system | PRIMARY       | NULL    | NULL    | NULL |    1 |                          |
+----+--------------------+-----------+--------+---------------+---------+---------+------+------+--------------------------+
simple: 简单的 select (没有使用 union或子查询)
mysql> explain select uid from testusers where uid=5;
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type   | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | testusers | system | PRIMARY       | NULL | NULL    | NULL |    1 |       |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+
dependent union: union 语句中的第二个select,依赖于外部子查询

subquery: 子查询中的第一个 select
mysql> explain select uid from testusers where uid >(select uid from testusers where uid=5);
+----+-------------+-----------+--------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table     | type   | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | PRIMARY     | NULL      | NULL   | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
|  2 | SUBQUERY    | testusers | system | PRIMARY       | NULL | NULL    | NULL |    1 |                                                     |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-----------------------------------------------------+
union: 第二层,在select 之后使用了 union。
UNION RESULT:UNION 中的合并结果。
mysql> explain select uid from testusers where uid=5 union   select uid from testusers where uid=1;
+----+--------------+------------+--------+---------------+------+---------+------+------+-------+
| id | select_type  | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra |
+----+--------------+------------+--------+---------------+------+---------+------+------+-------+
|  1 | PRIMARY      | testusers  | system | PRIMARY       | NULL | NULL    | NULL |    1 |       |
|  2 | UNION        | testusers  | system | PRIMARY       | NULL | NULL    | NULL |    1 |       |
| NULL | UNION RESULT | | ALL    | NULL          | NULL | NULL    | NULL | NULL |       |
+----+--------------+------------+--------+---------------+------+---------+------+------+-------+



table
记录查询引用的表。

type :表连接类型,主要有以下几种
system:表只有一行记录(等于系统表)。这是 const表连接类型的一个特例。
explain select uid from testusers where uid=5;
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type   | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | testusers | system | PRIMARY       | NULL | NULL    | NULL |    1 |       |
+----+-------------+-----------+--------+---------------+------+---------+------+------+-------+

const:表中最多只有一行匹配的记录,它在查询一开始的时候就会被读取出来。
eq_ref:从该表中会有一行记录被读取出来以和从前一个表中读取出来的记录做联合。
ref:该表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录作联合。
ref_or_null: 这种连接类型类似 ref,不同的是mysql会在检索的时候额外的搜索包含null 值的记录。
比如select * from ref_table where key_column=expr or key_column is null;

unique_subquery: 这种类型用例如一下形式的 in 子查询来替换 ref:
比如这种情况,primary_key是唯一的。
value in (select primary_key from single_table where some_expr)

index_subquery: 这种连接类型类似 unique_subquery。
比如下面这种情况 key_column不唯一
value in (select key_column from single_table where some_expr)

range: 只有在给定范围的记录才会被取出来,利用索引来取得一条记录。

index: 连接类型跟 all 一样,不同的是它只扫描索引树。

all: 将对该表做全部扫描以和从前一个表中取得的记录作联合。


possible_keys :可能会被用到的索引,里面所包含的索引可能在实际的使用中没用到。如果这个字段的值是null,就表示没有索引被用到。这种情况下,就可以检查 where子句中哪些字段那些字段适合增加索引以提高查询的性能。

key字段显示了mysql实际上要用的索引。当没有任何索引被用到的时候,这个字段的值就是null。想要让mysql强行使用或者忽略在 possible_keys字段中的索引列表,可以在查询语句中使用关键字force index, use index,或 ignore index。

key_len 字段显示了mysql使用索引的长度。

ref 字段显示了哪些字段或者常量被用来和 key配合从表中查询记录出来。

rows 字段显示了mysql认为在查询中应该检索的记录数。

extra
本字段显示了查询中mysql的附加信息
distinct:mysql当找到当前记录的匹配联合结果的第一条记录之后,就不再搜索其他记录了。
not exists:mysql在查询时做一个 left join优化时,当它在当前表中找到了和前一条记录符合 left join条件后,就不再搜索更多的记录了
select * from t1 left join t2 on t1.id=t2.id where t2.id isnull; //id如果是索引的话,extra 会显示using index。

Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通过集到的统计信息判断出不可能存在结果;
mysql> explain select uid from testusers  where uid=3;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
No tables:Query 语句中使用FROM DUAL 或者不包含任何FROM 子句;
mysql> explain select 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | No tables used |
Using filesort:当我们的Query 中包含ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。

mysql> explain select * from username order by name;
+----+-------------+----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | username | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using filesort |
Using index:所需要的数据只需要在Index 即可全部获得而不需要再到表中取数据;
Using index for group-by:数据访问和Using index 一样,所需数据只需要读取索引即可,而当Query 中使用了GROUP BY 或者DISTINCT 子句的时候,如果分组字段也在索引中,Extra 中的信息就会是Using index for group-by(松散索引扫描);

Using temporary:当MySQL 在某些操作中必须使用临时表的时候,在Extra 信息中就会出现Using temporary 。主要常见于GROUP BY 和ORDER BY 等操作中。
mysql> explain select uid,name ,max(uid)  from testusers group by uid ;
+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra                           |
+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+
|  1 | SIMPLE      | testusers | ALL  | NULL          | NULL | NULL    | NULL |    2 | Using temporary; Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+------+---------------------------------+
Using where:如果我们不是读取表的所有数据,或者不是仅仅通过索引就可以获取所有需
要的数据,则会出现Using where 信息;


你可能感兴趣的:(Mysql索引,null,subquery,mysql,table,system,query)