好程序员
Java
学习路线之
MySQL
的执行计划。什么是执行计划?
执行计划通常是开发者优化
SQL
语句的第一步。
MySQL
在解析
SQL
语句时,会生成多套执行方案,然后内部会进行一个成本的计算,然后通过优化器选择一个最优的方案执行,然后根据这个方案会生成一个执行计划。开发者通过查看
SQL
语句的执行计划,可以直观的了解到
MySQL
是如何解析执行这条
SQL
语句的,然后再针对性的进行优化。
如何查看
SQL
语句的执行计划?
语法:
explain select
语句
;
执行计划每个字段的含义:
id
(重要)
:主要用来标识
SQL
语句的解析执行顺序
id
相同的情况:
id
不同的情况:
id
相同不同同时存在:
id
为
null
的情况:
比较少见,
id
为
null
的部分一定是最后执行的
select_type:主要用来标识当前查询的类型
mysql
查询的分类:
简单查询:没有子查询以及
union
的
sql
复杂查询:
where
和
select
后面有子查询
from
后面有子查询
包换
union
关键字
SIMPLE
:标识当前查询是一个简单查询
PRIMARY
:如果是一个复杂查询(子查询或者
union
),则最外层的
SQL
语句会被标记成这个类型
SUBQUERY
:用来标记一个子查询(
where
、
select
)
注意:通常来说被标记成
PRIMARY
的部分,是最后执行的部分
DERIVED
:用来标记一个衍生查询(
from
后面的子查询)
UNION
:标记
union
关键字后面的查询部分
UNION RESULT
:标记
union
结果的合并部分
type(
重要
)
:用来标识当前这条
SQL
语句是用哪种方式访问的数据行(最差
->
最优)
all
:表示当前
MySQL
是采用全表扫描的方式访问的数据行
index
:表示当前是按照全索引扫描的方式访问所有数据行
range
:表示查询了索引的某个范围
ref
:表示查询了索引的某个值,但是这个值是可能重复的(只会出现在非唯一性索引的字段上)
eq_ref
:表示查询了索引的某个值,但是这个值是唯一的(只会出现在主键、唯一性索引上,并且需要结合连接查询)
const
:查询索引的某个唯一性值,
mysql
会将这个条件优化成一个常量
system
(正式开发基本不会出现):表示
mysql
可以确定查询的表结果一定只有一条
null
(性能最好,但是作用不大):表示当前
SQL
语句直接在解析时就能获得结果,不能去查询记录行
注意:通常在实际开发过程中,需要将
SQL
语句优化到
range
以上的级别,但是一定要具体问题具体分析,有些时候
all
反而是更好的行为。
possible_keys
:用来标记当前这条
SQL
语句可能用上的索引列表
key
(重要)
:用来标识当前这个
SQL
语句用上了哪个索引
注意:有可能一个索引出现在
possible_keys
中,但是没有出现在
key
中;也有可能一个索引出现在
key
中,但是没有出现在
possible_keys
中。
explain select * from student force index(idx_age) order by age;
标识手动设置
MySQL
执行的索引,但是最好不要这么干
key_len:标识当前使用到的索引长度,这个值越大,说明越多的条件使用上了索引
rows(
重要
)
:表示当前查询可能访问的记录行数,这个值越小越好,最好显示
1
注意:通常在实际的优化过程中,需要参考
type
和
rows
两个字段来决定是否需要进行优化。
比如
type
为
all
,但是
rows
为
1
,这种情况下,其实完全无需优化。
比如
type
为
ref,
但是
rows
为
10W
,那么这条
sql
语句性能肯定比不上
all - 1
Extra(
重要
)
:表示当前一些额外的信息显示的地方
Using index
:说明当前的执行计划用上了覆盖索引。
Using temporary
:说明当前内部使用了临时表
(
分组、排序
)
Using filesort
:说明使用了文件排序,这个排序有可能在内存上排序,也有可能在硬盘上排序,如果是在硬盘上排序,则最好优化一下(比如通过索引进行排序)
Using where
:表示使用了过滤条件