码农庄园

MySQL索引优化explain的字段介绍入门版小记

2024-05-23  本文已影响0人  小马过河R

explain字段可以分优先顺序看,但是要结合着看。


一、字段

【type】:查询计划对某个表的查询方式,表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围

依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL

一般来说,得保证查询达到range级别,最好达到ref。

NULL:

system:  表数据只存在一条出现该属性值;表中只有一条数据,这个类型是特殊的 const 类型。

const:   查询条件只使用唯一索引(索引列值是唯一的),且最终结果只有一条记录(索引只扫描一次);(比较理想的状态)

表连接情况下,使用连接字段为唯一索引,且最终连接结果只有一条结果匹配(索引只扫描一次);

eq_ref:与const一样,只使用唯一索引,但是匹配结果是多条;

ref:查询条件或者连接条件出现非唯一索引;(比较经常看到的是这个)

range:查询条件索引字段出现范围查询,如in,or等;这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中。

index:使用到了索引,即为index;type=index 执行效率仅高于全表扫描,是扫描了全部索引后才完成的操作,在某些情况下比全部扫描更差。key_len比较大,说明索引太长。

All:没有索引或全表扫描。全表扫描,MYSQL扫描全表来找到匹配的行。

【possible_keys】:查询时可能使用到哪些索引。

explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。

【key】:实际上使用到的索引。

【key_len】:显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

这一列显示mysql实际采用哪个索引来优化对该表的访问。如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 force index、ignore index。

【ref】:在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名。

【rows】:扫描出的行数(很有参考意义),这个是个估算的值,并不是真正的结果集。(mysql估计要读取并检测的行数,注意这个不是结果集里的行数。)

【Extra】:展示的是额外信息。Extra,主要看使用 order by 进行排序时有没有出现 Using filesort 和 Using index。

尽量通过 order by 和 where 配合,可以出现 Using index。避免 Using filesort。

那么什么时候会出现 Using index 呢?order by 语句满足索引最左前缀,where 和 order by 条件列组合满足索引最左前缀。

Using index:表示使用了覆盖索引,速度比较快。

Using where:使用 where 语句来处理结果,并且查询的列未被索引覆盖。(这种情况一般需要优化了)。

Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围。

Using temporary:mysql需要创建一张临时表来处理查询。(出现这种情况一般是要进行优化的),首先是想到用索引来优化。

Using filesort:将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。(这种情况下一般也是要考虑使用索引来优化的。

Select tables optimized away:使用某些聚合函数(比如 max、min)来访问存在索引的某个字段。


二、小记

1、不同的表数据对同一个sql可能explain的结果会不一样,因为在不强制的情况下MySQL一般都有自己的想法选择索引;

2、通常情况下 等值匹配的索引命中理论上只要符合 左侧原则等即可,如过非等值匹配则另说。特别是 带有order by 条件的语句需要视情况配合where设置为组合索引才能生效。

如:select * from  tbname    where  A=1 and  B!=2  and  addTime<'20100305' order by addTime desc limit 1;

虽然此时很可能type=ref,但是Extra是Using where;Using filesort等。此时并不代表索引OK。

若此时索引为 A,addTime。则Using where还可能Using filesort。要特别注意,带 order by的语句如果不是和where 组合索引而是各自字段索引很可能就是Using filesort,需要优化。通常我们会误以为 对where和order by 的各自字段单独建立索引就可以命中的。

若此时索引为 (A,addTime)。则Using where。此时应该关注 A字段索引是否是可以查一条,即rows=1。当A基本为相同值时,例如日期,但是同一日期的数据有可能几十万条时,则说明rows约等于几十万,也就是要扫描这么多数据,则索引索引命中但基本不发挥作用,应优化。

鉴于A字段建立的索引基本是相同值,所以考虑将A索引弃用。考虑调整为where  B!=2  and addTime<'20100305' order by addTime desc limit 1;  若此时索引为addTime字段。一般情况下,此时会用上索引 addTime但是有可能因为 addTime<'20100305' 条件又要扫描上千万条数据中去找  降序的最上面一条。也不合理。

最终,where  B!=2  order by addTime desc limit 1; 且若此时索引为addTime字段,则命中索引addTime且rows=1,这样才行。才不会慢查询。

其他参考资料:

参考1

参考2

参考3

上一篇下一篇

猜你喜欢

热点阅读