explain的使用浅谈

95 阅读4分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。

image.png

  1. Id: sql查询的序列号,表示查询中sql子句或操作表的顺序。包含下列几种情况。

    (1). Id相同,执行顺序由上至下。

    (2). Id不同,如果是子查询,id序号会递增,id值越大优先级越高,越先被执行。

    (3). Id相同不同,同时存在。(相同的认为是一组,从上到下执行,id值大的先执行)

  2. select_type表示查询的类型,用于区别普通查询,联合查询,子查询等复杂查询。

    (1). simple:简单的select查询,查询不包括子查询或union。

    (2). primary查询中包含任何复杂的子部分,最外层查询被标记为primary。

    (3). subquery在select或where中包含的子查询。

    (4). derived(衍生)在from列表中包含的子查询被标记为derived。

    (5). union若第二个select出现在union之后,则被标记为union,如union包含在from子句的子查询中,外层select将被标记为derived。

    (6). union result从union表获取结果的select

  3. table:当前执行的表

  4. type表示查询的连接类型:

    (1). system系统表,少量数据,往往不需要进行磁盘io。

    (2). const常量连接。

    (3). eq_ref主键索引或者非空唯一索引等值扫描。

    (4). ref非主键非唯一值索引等值扫描。

    (5). range范围扫描。

    (6). index索引树扫描。

    (7). All全表扫描。

一般至少要达到range级别,最好能达到ref级别。

  1. possible_keys可能应用的索引。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用到。

  2. key实际使用的索引,如果为null,则没有使用索引。(可能原因包括没有建立索引或索引失效)

  3. key_len表示索引使用的字节数,可通过该列计算查询中索引使用的长度,在不损失精度的情况下,长度越短越好。key_len显示的是索引字段的最大可能长度,并非实际使用长度。及是通过表定义计算得到的。

  4. ref显示索引的那一列被使用了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。 

  5. rows根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好 。

  6. Extra包含不适合在其他列中显式但十分重要的额外信息

    (1). using filesort 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”。 

    (2). using temporary使用了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序order by和分组查询group by。

    (3). using index 表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错。如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。

    (4). Using where表明使用了where过滤

    (5). Using join buffer表明使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些。

    (6). impossible where where子句的值总是false,不能用来获取任何元组

    (7). select tables optimized away在没有GROUPBY子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。

    (8). distinct优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作

    如有问题,请大佬指正