MySQL——explain
一. 执行计划名词释义
1. id
2. select_type
3. table
4. partitions
5. type
6. possible_keys
7. key
8. key_len
9. ref
10. rows
11. filtered
12. Extra
二. 实战
三. 歪个楼
执行计划名词释义
1. id
数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询。
2. select_type
3. table
显示查询表名,如果查询使用了别名,那么这里显示的是别名;如果不涉及对数据表的操作,那么这显示为null;如果显示为就表示这是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生;如果是,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。
4. partitions
查询匹配的记录来自哪一个分区对于分区表,显示查询的分区ID对于非分区表,显示为NULL
5. type
连接类型。依次从好到差:system=>const=>eq_ref=>ref=>fulltext=>ref_or_null=>unique_subquery=>index_subquery=>range=>index_merge=>index=>ALL除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。
6. possible_keys
可能使用到的索引都会在这里列出来
7. key
真正使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
8. key_len
处理查询的索引长度(幼儿园班车)
9. ref
如果是使用的常数等值查询,这里会显示const;如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段;如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func。
10. rows
这里是执行计划中估算的扫描行数,不是精确值。
11. filtered
存储引擎返回的数据在server层过滤后,剩下满足查询条件的比例,注意是百分比,不是具体记录数。
12. Extra
实战
explain select sum(oi.pay_amt),count(oi.order_id) from t_order_info oi where oi.mct_id='m201711210000984' AND oi.order_status='03' AND oi.order_id not in (select b.fq_order_id from t_order_info b where b.mct_id='m201711210000984' and b.order_status='09')
用时:4.391s
explain select sum(oi.pay_amt),count(oi.order_id) from t_order_info oi where oi.mct_id='m201711210000984' AND oi.order_status='03' AND
not EXISTS (select b.fq_order_id from t_order_info b where b.mct_id='m201711210000984' and b.order_status='09' and b.fq_order_id=oi.order_id)
用时:6.486s
分析:同一个业务,分别用not in和not exists实现性能查了50%,有执行计划来看主要是因为,第一个查询的ref列查询结果是const(常数)与key一起被使用;第二个查询的ref列查询结果是blpetpdb.oi.order_id列与key一起被使用。因此执行计划参数相同条件下,第二个查询性能比第一个差。
歪个楼
key_len计算
key_len表示索引使用的字节数 有两点需要注意: - 索引字段的附加信息:可以分为变长和定长数据类型,当索引字段为定长数据类型时,如char,int,datetime,需要有是否为空的标记,这个标记占用1个字节(对于not null的字段来说,则不需要这1字节);对于变长数据类型,比如varchar,除了是否为空的标记外,还需要有长度信息,需要占用两个字节。 - 对于,char、varchar、blob、text等字符集来说,key_len的长度与字符集有关,latin1一个字符占1个字节,gbk一个字符占用2个字节,utf8一个字符占用3个字节。
备注:key_len仅统计where后用于条件过滤的索引,不包含order by/group by部分选中索引字节长度;mysql的ICP特性使用到的索引不会计入其中。
反连接
使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。
番外
如果要排序、分组的数据类型有text / medium text ,那么排序/分组会发生在磁盘上。