在MySQL里,Explain都不会陌生,因为可以通过Explain查看SQL语句的预执行计划,这是目前分析SQL语句性能瓶颈常用的方式。Explain用法到MySQL8.0版本从简单方式延伸到EXPLAIN FORMAT=TREE,EXPLAIN FORMAT=JSON,EXPLAIN ANALYZE,EXPLAIN FOR CONNECTION多样化用法,并且输出内容更丰富。
MySQL的Innodb引擎是索引组织表,在Explain输出中SQL语句是否质量高,首先查看是否使用索引,还需要关注Filtered + Rows,key_len,Extra指标,最终体现在计算的COST成本中。
下面具体了解索引以外的,这些重点指标。
filtered
filtered是已筛选列表示按表条件筛选的表行的估计百分比。最大值为100,这意味着没有对行进行筛选。从100开始递减的值表示过滤量的增加。rows显示检查的估计行数,rows×filtered显示与下表连接的行数。例如,如果行为1000,过滤后的行为50.00(50%),则与下表连接的行数为1000×50%=500。
用来估算与其他表连接时扫描的行数,row x filtered = 101762 x 0.10% = 100行。很多场景下,超过28%左右比例,MySQL自身会选择全表扫描。
key_len
索引使用长度的字节数,根据这个值可以判断索引的使用情况,特别是在组合索引的时,判断该索引有多少部分被使用到非常重要。除此之外,一些长度长的索引,影响性能比较大。key_len只指示了where中用于条件过滤时被选中的索引列,是不包含Order by/Group by这一部分被选中的索引列。
每种类型所占的字节数如下:
类型 | 占用空间 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
char(n) | n个字节 | ||||||||||||
varchar(n) | 2个字节存储变长字符串,如果是utf-8,则长度 3n + 2 | ||||||||||||
tinyint | 1个字节 | ||||||||||||
smallint | 2个字节 | ||||||||||||
int | 4个字节 | ||||||||||||
bigint | 8个字节 | ||||||||||||
date | 3个字节 | ||||||||||||
timestamp | 4个字节 | ||||||||||||
datetime | 8个字节 | ||||||||||||
DECIMAL(M,D) | M字节(D+2 , 如果M CREATE TABLE `test1` ( `id` bigint NOT NULL AUTO_INCREMENT, `a` int NOT NULL, `b` int NOT NULL, `c` int NOT NULL, PRIMARY KEY (`id`), KEY `idx_mult` (`a`,`b`,`c`) ) ENGINE=InnoDB; mysql> EXPLAIN select * from test1 where a=1; mysql> EXPLAIN select * from test1 where a=1 and b=2; mysql> EXPLAIN select * from test1 where a=1 and b=2 and c=3;
ExtraExtra列包含有关如何解析查询的附加信息,却又十分重要。按照目前提供的官方说明,起码有36个信息可参考。
还有其他日常很少见的附加信息
2.No tables used
3.Distinct 4.unique row not found 5.Scanned N databases 6.Plan isn’t ready yet 7.Deleting all rows 总结了解和解读Explain输出信息,对SQL语句优化非常有必要。 |