如果时间足够多,看官网会更有收获explain,英语看不懂怎么说?直接用浏览器翻译成中文就可以愉快的学习了。
想要优化sql语句,首先看写的sql是否合理;那怎么来判断呢?使用explain就可以,explain是用于获取查询执行计划(即,有关MySQL如何执行查询的说明)
那怎么使用explain呢?很简单,在select语句前添加explain就可以了;(mysql版本:8.0.19)
格式:explain + select语句;
字段 | 含义 |
---|---|
id | 选择标识符 |
select_type | 表示查询的类型。 |
table | 输出结果集的表 |
partitions | 显示查询将访问的分区 |
type | 表示表的连接类型 |
possible_keys | 表示查询时,可能使用的索引 |
key | 表示实际使用的索引 |
key_len | 索引字段的长度 |
ref | 列与索引的比较 |
rows | 扫描出的行数(估算的行数) |
filtered | 按表条件过滤的行百分比 |
Extra | 执行情况的描述和说明 |
下面分别详细解释一下
id
SELECT的查询序列号;
id值越大越先被执行;id值相同执行顺序从上到下;
例子:
select_type
查询类型;挺多的就不一一详解了,挑选几个:
select_type | 含义 |
---|---|
SIMPLE | 没有子查询,就是简单的查询语句 |
PRIMARY | 有子查询时,外面的主查询类型为PRIMARY |
SUBQUERY | 子查询语句类型为SUBQUERY |
UNION | 在使用union时,第二个select语句的类型为union; |
UNCACHEABLE SUBQUERY | 一个子查询的结果不能被缓存 |
table
查询的表,如果使用别名,那显示的也是别名;
partitions
匹配记录的分区,在创建表的时候可以创建分区;这个不常用;我也没使用过,有兴趣的可以自己百度创建。。
type
连接类型;这个非常重要,关系到查询的效率;
type | 含义 |
---|---|
system | 结果只有一行(系统表),如果type类型是system,那查询性能最好 |
const | 该表最多具有一个匹配行,该行在查询开始时读取。因为只有一行,所以优化器的其余部分可以将这一行中列的值视为常量。 const表非常快,因为它们只能读取一次。在使用primary key(主键)或者UNIQUE index(唯一索引)作为查询条件时类型就是这个 |
eq_ref | 除了 system和 const类型,这是最好的联接类型。当联接使用索引的所有部分并且索引为 PRIMARY KEY或UNIQUE NOT NULL index(唯一索引不为空)时。 |
ref | 一般索引 |
range | 使用索引选择行,仅检索给定范围内的行;比如使用: <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE,或 IN() |
all | 全表扫描,性能非常差,最差的连接类型;遇到这种情况,可以建索引 |
index | 跟all差不多,只不过index是扫描索引树 |
性能高低:system > const>eq_ref>ref>range>index>all
还有其他几种链接类型,如果想想了解,请看官网:explain
possible_keys
可能使用到的索引
key
实际使用到的索引,这个也很重要,看清楚使用了什么索引;方便后面的sql优化;
key_len
实际使用索引长度
ref
该ref列显示将哪些列或常量与该key列中命名的索引进行比较
rows
该rows列表示MySQL认为执行查询必须检查的行数。
对于InnoDB表,此数字是估计值,可能并不总是准确的。
filtered
该filtered列指示按表条件过滤的表行的估计百分比。最大值为100,这表示未对行进行过滤。值从100减小表示过滤量增加。 rows显示检查的估计行数,rows× filtered显示与下表连接的行数。例如,如果 rows为1000且 filtered为50.00(50%),则与下表连接的行数为1000×50%= 500。
Extra
表示包含MySQL解决查询的额外信息;也很重要
Extra | 含义 |
---|---|
Full scan on NULL key | 该列有null值,扫描全表 |
Using temporary | 为了解决查询,MySQL需要创建一个临时表来保存结果。如果查询包含GROUP BY和 ORDER BY子句以不同的方式列出列,通常会发生这种情况 |
Using sort_union(…),Using union(…),Using intersect(…) | 这些指示了特定算法,该算法显示了如何针对index_merge联接类型合并索引扫描 官网 |
Using filesort | 当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序。Explain不会显示的告诉客户端用哪种排序。官方解释:“MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行 |
distinct | MySQL正在寻找不同的值,因此在找到第一个匹配的行后,它将停止为当前行组合搜索更多的行 |
Impossible HAVING | having条件总是为false |
Impossible WHERE | where条件总是为false |
No matching min/max row | 没有匹配到满足查询条件的min/max |
Using index | 仅使用索引树中的信息从表中检索列信息,而不必进行其他查找以读取实际行。当查询仅使用属于单个索引的列时; |
Using index for group-by | 与Using index表访问方法类似,Using index for group-by 表示MySQL找到了一个索引,该索引可用于检索GROUP BY或 DISTINCT查询的所有列,而无需对实际表进行任何额外的磁盘访问。此外,以最有效的方式使用索引,因此对于每个组,仅读取少数索引条目 |
Using where | 没有使用索引的查询条件 |
参考:
https://blog.csdn.net/poxiaonie/article/details/77757471
mysql官网