1.应用场景

主要用于生成/解释SQL的执行计划,分析SQL的性能。

MySQL EXPLAIN命令详解:优化SQL查询性能的利器

EXPLAIN是MySQL分析查询执行计划的核心命令,通过显示查询执行顺序、索引使用情况、扫描行数等关键信息,帮助开发者优化SQL性能。命令基础用法为"EXPLAIN SELECT...",输出包含type(访问类型)、key(使用索引)、rows(扫描行数)等字段。其中type字段尤为重要,按性能排序从system(最优)到ALL(全表扫描)。优化建议包括:避免ALL类型、确保使用合适索引、减少扫描行数、消除临时表和文件排序。MySQL 8.0+还支持JSON格式输出,提供更详细的执行计划分析。通过合理使用EXPLAIN,可显著提升查询效率。

2.学习/操作

MySQL EXPLAIN 命令详解

EXPLAIN 是 MySQL 中用于分析查询执行计划的关键命令,能够帮助开发者优化 SQL 查询性能

通过 EXPLAIN,可以获取查询的执行顺序、使用的索引、扫描的行数等信息。

EXPLAIN 的基本用法

在 SQL 查询前加上 EXPLAIN 关键字即可查看执行计划:

EXPLAIN SELECT * FROM users WHERE id = 1;

EXPLAIN 的输出包含多个字段,每个字段提供了查询执行的不同信息:

  • id:查询的序列号,表示查询中 SELECT 语句的执行顺序。
  • select_type:查询类型,如 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。
  • table:查询涉及的表名。
  • partitions:匹配的分区信息。
  • type访问类型,如 ALL(全表扫描)、index(索引扫描)、range(范围扫描)等。
  • possible_keys可能使用的索引。
  • key实际使用的索引。
  • key_len:使用的索引长度。
  • ref:显示索引的哪一列被使用。
  • rows:预估需要扫描的行数。
  • filtered:返回结果的行数占扫描行数的百分比。
  • Extra:额外信息,如 Using where、Using index 等。

如何解读 EXPLAIN 结果

type 字段:这是优化查询的关键指标之一

常见的类型按性能从高到低排序:

  • system:表中只有一行数据。
  • const:通过主键或唯一索引查询,返回一行数据。
  • eq_ref:多表连接时使用主键或唯一索引作为关联条件。
  • ref:使用非唯一索引查找。
  • range:使用索引进行范围扫描。
  • index:全索引扫描。
  • ALL:全表扫描。

Extra 字段:提供额外的重要信息:

  • Using index:表示查询使用了覆盖索引,无需回表。
  • Using where:表示存储引擎检索行后再进行过滤
  • Using temporary:表示查询需要创建临时表。
  • Using filesort:表示需要对结果进行外部排序。

使用 EXPLAIN 优化查询

识别全表扫描:如果 type 为 ALL,通常表示查询没有使用索引,需要检查是否可以为相关列添加索引

检查索引使用情况:观察 possible_keys 和 key 字段,确保查询使用了合适的索引。如果 possible_keys 有值但 key 为 NULL,可能需要优化查询或索引。

减少扫描行数:rows 字段显示预估扫描的行数。数值过大可能意味着需要优化索引或查询条件。

避免临时表和文件排序:Extra 字段中出现 Using temporary 或 Using filesort 通常表示性能瓶颈,可以通过优化 GROUP BY 或 ORDER BY 子句来解决。

高级用法:EXPLAIN FORMAT=JSON

MySQL 8.0 及以上版本支持以 JSON 格式输出更详细的执行计划信息:

EXPLAIN FORMAT=JSON SELECT * FROM users WHERE id = 1;

JSON 格式的输出包含更多细节,如成本估算、子查询的执行计划等,适合深入分析复杂查询。

解析JSON格式的查询执行计划

该JSON结构展示了一个MySQL查询的执行计划(EXPLAIN输出),主要针对users表的查询分析。以下是关键信息的拆解:

查询基础信息

  • 查询成本query_cost值为1.00,表示优化器估算的查询总成本较低。
  • 表名:操作对象为users表,访问类型标记为const,说明通过主键或唯一索引进行常量条件查询。

索引使用情况

  • 可能使用的键possible_keys仅包含PRIMARY,说明查询仅考虑主键索引。
  • 实际使用的键key确认使用主键索引,且used_key_parts显示仅用到id列。
  • 键长度key_length为4字节,符合典型的INT类型主键存储大小。

数据访问细节

  • 筛选效率rows_examined_per_scanrows_produced_per_join均为1,结合filtered: 100.00%表明精确命中一条记录。
  • 引用类型ref值为const,说明WHERE条件使用常量值(如id = 123)。

资源消耗

  • 读取成本read_cost为0.00,因数据可能已在缓存中。
  • 计算成本eval_cost为0.10,属于极低的计算开销。
  • 前缀成本prefix_cost为0.00,表示无多表连接时的累积成本。

涉及的列

used_columns列出所有被访问的字段,包含用户权限、状态标记、时间戳等业务字段,如:

  • 授权状态(authorization
  • 封禁标记(block
  • 黑白名单标识(white, black
  • 时间信息(created_at, updated_at

性能优化建议

该查询已通过主键实现高效访问,无需额外优化。若需进一步验证,可检查:

  • 表数据量是否影响缓存效率
  • 高频查询是否适合使用覆盖索引

实际案例

假设有一个查询:

EXPLAIN SELECT u.name, o.amount 
FROM users u 
JOIN orders o ON u.id = o.user_id 
WHERE u.status = 'active' 
ORDER BY o.created_at;

优化步骤:

  1. 确保 users 表的 status 字段和 orders 表的 user_id 字段有索引。
  2. 检查 ORDER BY 是否导致文件排序,考虑为 created_at 添加索引。
  3. 如果连接操作效率低,可以尝试调整连接顺序或使用 STRAIGHT_JOIN。

通过分析 EXPLAIN 结果并针对性优化,可以显著提升查询性能。

后续补充

...

3.问题/补充

TBD

后续补充

...

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐