Sql语句的执行过程
Explain关键字
作用: 可以模拟查询优化器对Sql的执行计划做一个展示,看看我们是否还有优化的空间。
关键字段: id、selecttypt、table、type、possible_keys、key、key_len、ref、rows、extra
Explain关键字段详解
id
- id字段的取值是一个数字,表示的是执行计划的执行顺序,这会体现在数字的大小上。
- id相同,执行顺序从上到下执行(ex:简单的join语句)
- id不同,id的序号递增,执行顺序从下到上(ex:子查询)
select_type
- select_type表示的是查询类型,主要用于查询是普通查询、联合查询、子查询、union查询等等复杂执行
- 分类:
- simple:表示简单的select查询
- primary:查询中包含任何复杂的子部分,最外层就会被标记为primary
- subquery:表示子查询
- deliver: 表示派生表查询
- union:表示查询方式为合并
type
type字段显示的是连接类型,type描述了找到所需要的数据,所使用的扫描方式,是一个非常重要的指标。
类型
-- 完整的连接类型比较多
system > const > eq_ref > ref > fulltext > ref_or_nul1 > index_merge > unique_subquery> index_subquery > range > index > ALL
-- 简化之后,我们可以只关注一下几种
system >consit > eq_ref> ref> range > index > ALL
type字段值的含义
一般来说,需要保证查询至少到range级别,最好是能到ref,否则就证明我们的SQL需要进行优化调整。type字段值的含义:
-
system:表中就仅仅只有一行数据的时候,比较少见。
-
const:const表示命中的是主键索引或者是唯一索引,表示通过索引一次就获取到的对应的数据记录
-
eq_ref:对于前一个表中的每一行,后表只有一行被扫描。只有当连接使用索引的部分都是主键或者唯一非空索引时,才会出现。
-
ref:使用了普通索引(非唯一性索引),对于前表的每一行,后表有可能有多于一行的数据被扫描,会返回所有匹配某个单独值的行。
-
range:索引上的范围查询,检索给定范围的行。between、in函数、>、<都是范围查询
-
index:出现index表示SQL使用了索引,但是没有通过索引进行过滤。需要扫描索引上的全部数据。
-- 使用索引进行分组或排序 EXPLAIN SELECT * FROM user GROUP BY userId ORDER BY userId -- count查询 需要通过扫描索引上的全部数据进行统计 EXPLAIN SELECT COUNT(*) FROM user;
-
all:没有使用索引,全表扫描
possible_key与key
- possible_key表示可能应用到这张表上的索引
- key表示实际使用到的索引
- 没有建立索引
- 建立的索引失效了
key_len
key_len:表示索引中使用的字节数,可以通过该列计算查询中使用的索引的长度。
key_len字段能够帮助你检查是否充分的利用了索引,ken_len越长,说明索引利用的越充分。
在使用联合索引时这个字段显得比较重要。
ref
- 如果使用的是常数等值查询,ref会显示const
- 如果是连接查询,被驱动表的执行计划里,ref字段会显示驱动表关联的字段
row
- rows表示mysql在进行数据检索的时候,估算的找到需要的行记录,可能会要读取的行数。
- rows只是一个估算的值,结果并不准确
partitions
- 该列显示的是分区情况,表示命中的是哪一个分区,非分区表字段为null
filtered
- 它指的是返回结果行数,占用所要读取的行的百分比
extra
-
using filesort: 表示得到我们想要的查询结果,需要对所有记录进行文件排序。文件排序性能非常差,需要优化。
explain select * from user order by age
-
using temporary: 表示需要临时表来存储临时数据
explain select count(*),name from user order by name
-
using where: 表示查询的列未被索引覆盖,意味着需要全表扫描。需要建立索引优化查询。需要结合type的值进行查看。
explain select * from user where age = 18
-
using index: 表示直接访问索引就能够获取到所需要的数据。一种情况是使用聚簇索引,另外一种情况就是使用的覆盖索引。不需要回表。
-
using join buffer: 使用了连接缓存
-
using index condition: 表示使用了索引下推,对查询进行了优化,减少回表次数。using index condition只适用于二级索引。
索引
当主键加了索引,通常情况下可以一次命中。
索引是一种数据结构,它存储了列值和对应的行位置信息,使得数据库系统可以快速定位到具有特定值的记录。当主键字段加上索引后,数据库可以通过索引直接找到满足查询条件的记录,而无需进行全表扫描。这样,在查询时通常可以一次命中目标记录,提高查询效率。