MySQL EXPLAIN 解读

166 阅读4分钟

1.EXPLAIN 解读

在优化 MySQL 查询时,EXPLAIN关键字是深入了解查询执行计划的重要工具。通过在查询语句前加上EXPLAIN,MySQL 会返回关于如何执行该查询的详细信息,帮助我们分析查询性能瓶颈并进行针对性优化。

当我们使用EXPLAIN时,MySQL 会返回包含多个列的结果集,每个列都提供了关于查询执行计划的特定信息。主要的列及其含义如下:

1.1 id

id是查询中每个 SELECT 子句的唯一标识符。在复杂查询中,可能会有多个SELECT语句,id值用于确定这些语句的执行顺序。一般来说,id值越大,执行优先级越高。如果id值相同,则按照从上到下的顺序执行。

1.2 select_type

select_type表示查询的类型,常见的类型有:

SIMPLE:简单查询,不包含子查询或 UNION。

PRIMARY:最外层的查询。

SUBQUERY:子查询中的第一个 SELECT。

DERIVED:在 FROM 子句中包含的子查询,也称为派生表。了解select_type有助于我们分析查询的结构,特别是在处理复杂查询时,判断哪些部分是子查询或派生表,从而优化查询结构。

1.3 table

table显示了EXPLAIN输出结果对应的表名。在连接查询中,它会列出参与连接的各个表。

1.4 partitions

partitions表示查询将访问的分区。如果表是分区表,这一列会显示具体访问的分区信息。对于非分区表,该列显示为NULL

1.5 type

type表示连接类型,它反映了 MySQL 找到所需行的方式,从最佳到最差依次为:

system:表只有一行记录(系统表),这是const类型的特例,这种情况非常少见。

const:通过索引一次就找到,常用于主键或唯一索引的等值查询。例如,SELECT * FROM users WHERE id = 1,如果id是主键,那么该查询的连接类型就是const

eq_ref:对于每个来自前面表的行组合,从该表中读取一行。这通常发生在连接条件是主键或唯一索引的等值匹配时。例如,在SELECT * FROM orders JOIN customers ON orders.customer_id = ``customers.id查询中,如果customers.id是主键,那么customers表的连接类型可能是eq_ref

ref:使用非唯一索引来查找匹配行,即通过索引查找多个符合条件的行。例如,SELECT * FROM users WHERE name = 'john',如果name列有索引,那么连接类型可能是ref

range:只检索给定范围的行,使用一个索引来选择行。常见于WHERE子句中使用BETWEENIN>、<等操作符的查询。例如,SELECT * FROM orders WHERE create_time BETWEEN '2023 - 01 - 01' AND '2023 - 12 - 31',如果create_time列有索引,连接类型可能是range

index:全索引扫描,遍历整个索引树。虽然比全表扫描快,但如果索引很大,仍然会消耗大量资源。

ALL:全表扫描,从表的第一行开始,依次读取每一行,直到找到所有符合条件的行。这是最差的连接类型,通常意味着查询性能不佳,需要优化。

1.6 possible_keys

possible_keys列出了在查询中可能使用到的索引。然而,这并不意味着 MySQL 实际会使用这些索引,实际使用的索引会在key列中显示。

1.7 key

key显示了 MySQL 实际使用的索引。如果为NULL,则表示没有使用索引。通过对比possible_keyskey,我们可以判断是否选择了最优索引。

1.8 key_len

key_len表示 MySQL 使用的索引长度。通过这个值,我们可以了解到索引使用的具体情况,例如联合索引中实际使用了哪些部分。

1.9 ref

ref显示了哪些列或常量被用于查找索引列上的值。例如,在SELECT * FROM users WHERE name = 'john'查询中,如果name列有索引,ref列可能显示为const,表示使用常量'john'来查找索引值。

3.4.10 rows

rows表示 MySQL 为了找到所需行而估计需要读取的行数。这个值是一个估计值,并非实际行数,但可以帮助我们大致了解查询的工作量。

3.4.11 filtered

filtered表示存储引擎返回的数据在表条件过滤后,剩下满足查询条件的记录数量的百分比估计值。

通过对EXPLAIN输出结果的详细分析,我们可以判断查询是否使用了正确的索引、表连接顺序是否合理等。例如,如果type列显示为ALL,则可能需要考虑添加索引或优化查询语句;如果key列为NULL,说明没有使用索引,需要检查索引的创建和使用是否正确。在实际优化工作中,结合EXPLAIN的分析结果,针对性地调整索引、查询语句或数据库配置,能够有效提升查询效率。