MySQL-执行计划

MySQL 的执行计划是数据库优化器为 SQL 查询生成的执行方案,它详细描述了 MySQL 如何执行该查询,包括表的读取顺序、使用的索引、数据访问方式等信息。通过分析执行计划,我们可以了解查询的性能瓶颈,并进行相应的优化。
1. 什么是执行计划?
简单来说,执行计划就是 MySQL 告诉我们它将如何执行我们的 SQL 查询的“蓝图”。它展示了查询的执行步骤、使用的算法、以及可能存在的性能瓶颈。
2. 如何查看执行计划?
使用 EXPLAIN
关键字放在 SQL 语句前面即可:
EXPLAIN SELECT * FROM users WHERE name = '张三' AND age > 20;
3. 执行计划包含哪些信息?
EXPLAIN
命令会返回一系列列,其中一些重要的列包括:
- id: 查询的标识符,表示查询中执行 select 子句或操作表的顺序。如果 id 相同,则执行顺序从上到下;如果 id 不同,则 id 值越大优先级越高,越先执行。
- select_type: 查询类型,常见的有:
SIMPLE
:简单查询,不包含子查询或 UNION。PRIMARY
:最外层查询。SUBQUERY
:子查询。DERIVED
:派生表(FROM 子句中的子查询)。UNION
:UNION 操作的第二个或后续的查询。UNION RESULT
:UNION 的结果。
- table: 正在访问的表名。
- partitions: 查询将访问的分区。
- type: 访问类型,表示 MySQL 如何查找表中的行,从最佳到最差的排序如下:
system
:表只有一行记录(等于系统表),这是 const 连接类型的一个特例。const
:表最多有一个匹配行,它将在查询开始时被读取。因为只有一行,所以优化器的其余部分可以将此行中列的值视为常量。const 表非常快,因为它们只读取一次。eq_ref
:对于来自先前表的每一行,此表只有一行匹配。这通常发生在主键或唯一非 NULL 索引的连接中使用。ref
:对于来自先前表的每一行,此表中有多行匹配。这通常发生在索引查找中使用。range
:给定范围内的行,使用索引来选择行。index
:此类型与 ALL 相同,除了只扫描索引树。这通常比 ALL 快,因为索引通常比数据表小。ALL
:全表扫描,MySQL 必须扫描整个表来找到匹配的行。这是最差的类型,应该尽量避免。
- possible_keys: 可能用于此表的索引。
- key: 实际使用的索引。如果没有使用索引,则为 NULL。
- key_len: 使用的索引的长度。
- ref: 将哪个列或常量与索引进行比较。
- rows: MySQL 估计要检查的行数。
- filtered: 按表条件过滤的行百分比。
- Extra: 包含有关 MySQL 如何解析查询的附加信息,一些重要的值包括:
Using index
:使用覆盖索引,表示查询只需要访问索引而无需访问数据行,性能很高。Using where
:使用了 WHERE 子句进行过滤,但没有使用索引。Using temporary
:MySQL 需要创建一个临时表来存储结果,这通常发生在排序或分组操作中,性能较差。Using filesort
:MySQL 需要对结果进行文件排序,而不是使用索引排序,性能很差。Using index condition
:使用了索引下推。Using join buffer (Block Nested Loop)
:使用了连接缓冲区。当被驱动表的没有使用索引的时候,MySQL 会先将驱动表读出来放到 join buffer 中,再遍历被驱动表与驱动表进行查询。
4. 如何通过执行计划进行优化?
- 避免全表扫描(type=ALL): 这是最常见的优化目标。通过添加合适的索引来避免全表扫描。
- 优化排序和分组(Using filesort 和 Using temporary): 尽量使用索引来避免文件排序和临时表。
- 使用覆盖索引(Using index): 尽量让查询只需要访问索引就能获取所有需要的数据,避免回表。
- 使用索引下推(Using index condition): 将部分过滤条件下推到存储引擎层,减少数据传输。
- 优化连接查询: 确保连接的列上有索引,并选择合适的连接方式。
总结
理解 MySQL 的执行计划是进行 SQL 优化的关键。通过分析执行计划,我们可以了解查询的执行过程,发现潜在的性能瓶颈,并采取相应的优化措施,提高查询效率。记住要关注 type
、key
、rows
和 Extra
等列,它们提供了最有用的信息。