MySQL执行计划是sql语句经过查询优化器后,查询优化器会根据用户的sql语句所包含的字段和内容数量等统计信息,选择出一个执行效率最优(MySQL系统认为最优)的执行计划,然后根据执行计划,调用存储引擎提供的接口,获取数据。
但是,在MySQL执行的时候,到底使用了一个什么样的执行计划,有没有用到索引。当数据规模比较大的时候,sql执行的时候,执行计划不同,会直接影响sql的执行速度。这个时候,就需要对sql语句执行进行调试。
MySQL我们在调试sql语句的时候,不会像我们写Java或者其他语言代码那样通过打断点的方式进行代码调试。这个时候,我们就需要通过查看执行计划来调试我们的sql了。MySQL通过EXPLAIN来查看执行计划,我们写sql语句的时候,在语句之前加一个EXPLAIN就可以了。EXPLAIN可以用在SELECT、DELETE、INSERT、PEPLACE以及UPDATE等语句中,如:
EXPLAIN SELECT
*
FROM
school
WHERE
school_nick = '县第一小学'
EXPLAIN SQL
执行后,结果如下:
这里介绍下每个字段以及每个字段的含义:
id
id是执行计划的标识符,是SELECT 查询的序号。如果结果集会跟其他表的结果用UNION关键字相结合,那么id可能为空。
id是否为空,对执行计划的影响不大。
select_type
select_type表示sql语句查询的类型。具体表示如下表:
select_type的值 含义SIMPLE 简单的select查询,没有使用关联和子查询。
PRIMARY 最外层select,包含子查询的时候,最外层的查询
UNION 在一个UNION查询中,第二次或以后的子查询操作
DEPENDENT UNION 在一个UNION查询中,第二次子查询或以后的SELECT查询的时候需要依赖外部的查询
UNION RESULT UNION的返回结果集
SUBQUERY 子查询语句的第一个select语句
DEPENDENT SUBQUERY 依赖外部查询的第一个子查询
DERIVED 派生表——该临时表是从子查询派生出来的,位于form中的子查询
MATERIALIZED 物化子查询(不确定啥意思,以后研究后再回来补充,或者大神指教)
UNCACHEABLE SUBQUERY 无法缓存结果的子查询,必须为外部查询的每一行重新计算
UNCACHEABLE UNION UNION中的第二个或以后的不可缓存的子查询。
table
输出行引用的表的名称。一般为表格名称或别名,也可能为如下值:
1.UNION的并集结果集。
2.derivedN当前行指向派生结果集。可能是一个派生表,例如来自FROM子句的结果集。
3.subqueryN 当前行指向一个子查询的结果集。
type
连接类型。该列输出表示如何连接表。下面的类型表示从最好的到最坏的类型
1.system 该表只有一行(=系统表)。这是const连接类型的特例 。
2.const 最多只有一行匹配,在查询开始的时候,计算出常量对应的地址,直接访问,例如:select * from test where name ='zhang' 当name是唯一索引的时候,就有可能出现const。const非常快,因为它只读一次。
3.eq_ref 除了 system和 const类型之外,这是最好的连接类型。当两个表联查时使用索引的所有部分(针对的是组合索引),且索引是 主键或唯一索引时使用它。使用“=”运算符来进行索引列的比较。
4.ref 非唯一索引扫描,返回某个匹配值的所有行。常用语非唯一索引。这里对于eq_ref 和ref不熟悉的同学,可以看以下代码:
-- 给test表的name字段加唯一索引,test2 的job 行添加非唯一索引。
-- 这个代码执行后,首先执行test2 的查询,查出job = ‘teacher’ 的所有集合。
-- 所以test2 的typ是ref 表示的是匹配job = ‘teacher’ 的一个结果集。
-- 然后从结果集中取出name的集合,去匹配test1.name的结果。因为test1.name是唯一索引,所以一个name最多匹配到一条记录,所以test的type是ref
EXPLAIN SELECT
*
FROM
test,
test2
WHERE
test. NAME = test2. NAME
AND test2.job = '33'
test ref and eq_ref
执行结果如下图:
5.fulltext 使用fulltext 索引进行查询。
6.ref_or_null 这种链接类型类似于ref,但是,除了ref之外,还对包含null的值进行了搜索。常用于解析子查询。代码示例如下:
SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;
7.index_merge 这个链接类型表示使用索引合并优化。输出内容包含在索引列表中。
8.unique_subquery 索引查找,替换子查询,以提高效率。
value IN (SELECT primary_key FROM single_table WHERE some_expr)
9. index_subquery 类似于unique_subquery 但是替换in子查询,适用于非唯一索引,代码: value IN (SELECT key_column FROM single_table WHERE some_expr)
10.range 扫描部分索引,对索引的扫描从某一点开始,返回的是某个索引区域的值。常见的有基于索引的 < ,> 等的查询。
11. index 扫描全部索引,对索引进行整体扫描。
12.all 全表扫描,最慢的查询 。应该避免
possible_keys
可能使用的key,指出当前查询涉及到的行都含有那些索引。如果有索引就会列出,但是不一定会被使用。
key
实际使用的索引。如果没有使用索引,显示null。
key_len