关于使用EXPLAIN执行计划详解
在我们开发过程中,往往避免不了数据库的使用,比如我使用的关系型数据库mysql,今天就给大家聊聊这个执行计划怎么使用?
其实使用方式就是 explain 加上我们的查询语句,如下:
EXPLAIN select id, name from student;
是不是很简单,关键是我们得知道执行计划的结果怎么看
如上图所示,可以看到有很多列,我们需要知道各列的含义是什么?
id列
id列在EXPLAIN的输出中表示查询的标识符。每个SELECT子句都有一个唯一的标识符,这个标识符用于表示查询的执行顺序和层次结构。id列的值越小,表示该查询的优先级越高。当有多个查询时,MySQL会根据id列的值来确定它们的执行顺序
select_type列
select_type列表示查询中每个SELECT子句的类型,具体值得介绍:
1.SIMPLE:对于不包含子查询和其他复杂语法的简单select查询,这是常见的类型。
2.PRIMARY:对于更复杂的查询,如果它是更外层的查询,通常被标记为PRIMARY。这个类型通常在DERIVED和UNION类型混合使用时见到。
3.DERIVED:当一个表不是一个物理表时,它被称为DERIVED。
4.UNION:当一个查询包含UNION操作时,这个查询的结果会被标记为UNION。
5.RESULT:这是在UNION语句中的表的返回结果。
6.MATERIALIZED表示该SELECT子句的结果被存储在一个临时表中,以便其他子句可以更高效地使用它。
table列 这个就不用详细说了,见名知意
partitions列
表示查询涉及的分区。分区是一种将表的数据分成多个物理子表的方法,这些子表在逻辑上被视为单个表,但在物理上存储在不同的位置。每个子表称为一个分区。
当你在查询中使用了分区表时,partitions列会显示查询涉及的分区数量。通过查看这个列,你可以了解查询是否有效地利用了分区,以及是否需要进一步优化查询以更好地利用分区。
type列
表示了MySQL如何找到需要的数据行。这个列提供了从最差到最好的查询效率的顺序信息。以下是type列中常见的值及其含义:
1.ALL: 全表扫描,没有使用任何索引,从头到尾遍历整个表来找到所需的数据行。这是效率最低的查询方式。
2.index: 扫描全表,但是扫描的顺序是按照索引顺序进行的。这避免了排序操作,因为索引已经是排序好的,但是需要承担按照索引顺序读取整张表的开销。
3.range: 只检索给定范围内的行,使用一个索引来选择行。
4.ref: 非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独值的行。
5.eq_ref: 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
6.const: 表示通过索引一次就找到了。在比较主键或者唯一索引时使用,因为只匹配一行数据,所以很快。
7.system: 表只有一行记录(等于系统表),这是const类型的特例,通常不会出现,也可以忽略不计。
另外 index_merge表示MySQL使用了索引合并优化方法来检索行。
possible_keys列
同样比较见名知意,表示可能使用哪些索引在表中找到记录。该列显示了在查询涉及的字段上存在的所有索引,但并不意味着这些索引都会被实际使用。查询可以利用的索引如果没有被任何查询使用,将在possible_keys列中显示为null。
key列
key列在MySQL的EXPLAIN输出中表示实际使用的索引。MySQL会根据查询优化器的选择,选择合适的索引来执行查询。key列会显示实际使用的索引的名称。
如果key列显示为NULL,则表示没有使用索引。这可能是因为查询优化器认为全表扫描比使用索引更高效,或者因为没有可用的索引。
在分析EXPLAIN输出时,key列是非常重要的,因为它提供了关于查询实际使用的索引的信息。
key_len列
key_len是EXPLAIN输出中的一列,表示索引中使用的字节数。通过该列,可以计算查询中使用的索引的长度。
key_len显示的值为索引字段的最大可能长度,并非实际使用长度。也就是说,key_len是根据表定义计算而得,不是通过表内检索出的。在不损失精度的情况下,长度越短越好。
key_len字段能够帮你检查是否充分地利用上了索引。如果key_len越长,说明索引使用的越充分。
请注意,key_len只计算WHERE条件中用到的索引长度,而排序和分组即便是用到了索引,也不会计算到key_len中。
ref列
EXPLAIN 返回的 ref 列显示了哪些列或常量被用于查找索引列上的值。这可以帮助了解查询是如何使用索引的,从而进一步优化查询。
rows列
表示查询优化器估计需要检查的行数。这个数字是根据查询优化器的内部算法计算出来的,用于评估查询的性能。
这个数字只是一个估计值,实际的行数可能会根据索引的使用情况、表的数据分布等因素而有所不同。通过查看rows列,你可以了解查询优化器认为需要检查多少行来获取所需的结果。
如果rows列的值非常大,可能意味着查询的性能较差,需要进一步优化。优化的方法可能包括添加索引、修改查询条件、调整查询结构等。
需要注意的是,rows列只是一个估计值,实际的性能表现还需要考虑其他因素,如硬件性能、数据库配置等。因此,在优化查询时,需要综合考虑各种因素,以获得最佳的性能效果。
filtered列
EXPLAIN的“filtered”列显示了预计有多少行可以通过WHERE子句的条件。例如,如果filtered列显示为100%,这意味着预计所有行都满足WHERE子句的条件。如果filtered列显示为0%,则意味着没有行满足WHERE子句的条件。这个列可以帮助你了解查询的过滤效果,从而更好地优化查询。
extra列
extra列显示了额外的信息,提供了关于MySQL如何执行查询的额外细节。这些信息对于优化查询性能非常有用。一些常见的extra值包括:
1.Using index:表示MySQL使用了覆盖索引(covering index),即查询的所有字段都包含在索引中,不需要再次访问表。
2.Using where:表示MySQL在检索行后应用了WHERE子句中的条件。
3.Using index condition:表示MySQL使用了索引条件推送下(index condition pushdown)技术,将一部分WHERE条件应用于索引扫描,以减少需要检查的行数。
4.Using temporary:表示MySQL需要使用临时表来存储中间结果。这通常表明查询可能需要进行排序或分组操作,而且可能效率不高。
5.Using filesort:表示MySQL需要对结果进行外部排序。这通常比使用临时表更糟糕,因为磁盘I/O操作通常比内存操作更慢。
本次介绍大概就是这样,总之执行计划应该是我们每个程序员都要掌握的一个技能吧,加油!!!