mysql如何通过explain分析查询计划_mysqlSQL优化工具

6次阅读

type为all表示全表扫描,mysql未使用索引而逐行检查所有记录,是性能最差的访问类型之一。

mysql如何通过explain分析查询计划_mysqlSQL优化工具

EXPLaiN 输出中 type 字段为 ALL 代表什么

表示全表扫描,MySQL 没有使用任何索引,逐行检查所有记录。这是性能最差的访问类型之一,尤其在大表上会严重拖慢查询。

常见诱因包括:WHERE 条件列没建索引、索引失效(如对索引列做函数操作:WHERE YEAR(create_time) = 2023)、隐式类型转换user_idVARCHAR,但查询写成 WHERE user_id = 123)。

  • 先用 SHOW CREATE table 确认字段类型和现有索引
  • EXPLAIN format=TRADITIONALEXPLAIN FORMAT=json 查看更详细的索引选择逻辑
  • 避免在索引列上使用 LIKE '%abc'IS NULL(除非该列有单独索引且允许 NULL)

key 和 key_len 字段怎么看是否命中复合索引

key 显示实际使用的索引名,key_len 表示 MySQL 使用了该索引的前多少字节。它能帮你判断复合索引用了几列、是否用了最左前缀。

例如索引是 INDEX idx_status_type_time (status, type, create_time)key_len = 2 表示只用了 status(假设 TINYINT 占 1 字节 + 1 字节 null 标志),key_len = 5 可能表示用了 statustype(比如 VARCHAR(2) 占 2 字节 + 长度标识等)。

  • key_len 值越小,通常说明用到的索引列越少,覆盖范围越窄
  • 注意字符集影响:utf8mb4 下 VARCHAR(10) 最大占 40 字节(10×4),而 utf8 下是 30 字节
  • 如果 key 有值但 key_len = 0,很可能是索引仅用于排序或去重,未用于 WHERE 过滤

Extra 字段出现 using filesort 或 Using temporary 怎么办

这两个提示说明 MySQL 无法直接利用索引完成排序或分组,必须额外创建临时结构——通常是性能瓶颈信号。

Using filesort 出现在 ORDER BY 列没被索引覆盖时;Using temporary 多见于 GROUP BYDISTINCT、含子查询或 union 的场景,且无法通过索引消除中间结果集。

  • 优先让 ORDER BYGROUP BY 的字段落在复合索引最右位置,例如查 WHERE status = ? ORDER BY create_time,建 INDEX(status, create_time)
  • 避免 select * 配合 ORDER BY —— 如果只查几列,可建覆盖索引减少回表
  • Using temporaryGROUP BY 时若字段无索引,建索引往往比加 SQL_BIG_RESULT 更有效

为什么 EXPLAIN 的 rows 估算值和实际扫描行数差距很大

rows 是优化器基于统计信息预估的扫描行数,并非精确值。当表数据分布不均、长期未 ANALYZE TABLE、或存在大量重复值时,估算容易严重失真。

例如某字段只有 ‘A’/’B’ 两个值,但优化器误判为均匀分布,就可能选错索引甚至放弃使用索引。

  • 执行 ANALYZE TABLE table_name 更新统计信息(注意:会锁表,建议低峰期操作)
  • SHOW INDEX FROM table_name 查看 Cardinality 值,过低(如远小于总行数)说明统计不准
  • 对倾斜字段(如状态字段 99% 是 ‘active’),考虑用条件拆分查询或添加高频值过滤提示

真正卡住性能的,往往是 EXPLAIN 里没报错、没警告,但 rowskey_len 组合暴露出来的“看似走了索引,实则只擦边”的情况。

text=ZqhQzanResources