EXPLAIN

Mysql执行计划

1
explain select ...

id

子查询的执行顺序

  • id相同执行顺序由上至下
  • id不同,id值越大优先级越高,越先被执行。如果是子查询,id的序号会递增
  • id为null时表示一个结果集,不需要使用它查询,常出现在包含union等查询语句中

select_type

子查询的查询类型

select_type description
SIMPLE 简单的select查询 不包含任何子查询或union等查询
PRIMARY 查询中包含任何复杂的子部分,最外层查询则被标记为primary
SUBQUERY selectwhere 中包含了子查询
DERIVED from中包含的子查询被标记为derived(衍生)结果放在临时表****里
UNION 出现在union后的select语句中,若union包含在from子句的子查询中,外层select将被标记为derived
UNION RESULT 从UNION中获取结果集 id 为NULL <union1,2>

table

查询的数据表 table_name <derivedid> <unionid,id>

type

访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,好的sql查询至少达到range级别,最好能达到ref

  • system 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,可以忽略不计
  • const PRIMARY KEY或 UNIQUE索引的所有部分与常量值进行比较时使用
1
2
3
4
SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name
  WHERE primary_key_part1=1 AND primary_key_part2=2;
  • eq_ref 在join查询中使用PRIMARY KEY or UNIQUE NOT NULL索引关联 比较值可以是常量/表达式
1
2
3
4
5
6
SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
  AND ref_table.key_column_part2=1;
  • ref 非唯一性索引扫描,返回匹配某个单独值的所有行

  • fulltext 使用全文索引
  • ref_or_null 对Null进行索引的优化的 ref
  • index_merge 索引合并优化 单个表的索引扫描多行 range扫描和他们的结果合并到一个 and or
1
2
3
4
5
6
7
8
9
10
11
12
SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name
  WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

SELECT * FROM t1, t2
  WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
  AND t2.key1 = t1.some_col;

SELECT * FROM t1, t2
  WHERE t1.key1 = 1
  AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);
  • unique_subquery 在子查询中使用 eq_ref
  • index_subquery 在子查询中使用 ref
  • range 索引范围查找 where语句中出现了bettween、<、>、in等的查询
  • index 遍历索引
  • ALL 扫描全表数据

possible_keys

可能使用的索引,注意不一定会使用。查询涉及到的字段上若存在索引,则该索引将被列出来。当该列为 NULL时就要考虑当前的SQL是否需要优化了。

key

显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL。

key_length

索引长度

ref

表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

返回估算的结果集数目,并不是一个准确的值

extra

不适合在其他字段中显示,但是十分重要的额外信息

  • Using filesort

mysql对数据使用一个外部的索引排序,而不是按照表内的索引进行排序读取。也就是说mysql无法利用索引完成的排序操作成为文件排序

  • Using temporary

使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用了临时表,常见于order bygroup by

  • Using Index

    表示直接访问索引就能够获取到所需要的数据(覆盖索引),不需要通过索引回表;

  • Using Index Condition

    在MySQL 5.6版本后加入的新特性(Index Condition Pushdown);会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;

  • Using where

    表示MySQL服务器在存储引擎收到记录后进行“后过滤”(Post-filter),如果查询未能使用索引,Using where的作用只是提醒我们MySQL将用where子句来过滤结果集。这个一般发生在MySQL服务器,而不是存储引擎层。一般发生在不能走索引扫描的情况下或者走索引扫描,但是有些查询条件不在索引当中的情况下。