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

EXPLAIN 输出中 type 字段为 ALL 代表什么
表示全表扫描,MySQL 没有使用任何索引,逐行检查所有记录。这是性能最差的访问类型之一,尤其在大表上会严重拖慢查询。
常见诱因包括:WHERE 条件列没建索引、索引失效(如对索引列做函数操作:WHERE YEAR(create_time) = 2023)、隐式类型转换(user_id 是 VARCHAR,但查询写成 WHERE user_id = 123)。
- 先用
SHOW CREATE TABLE确认字段类型和现有索引 - 用
EXPLAIN FORMAT=TRADITIONAL或EXPLAIN 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 可能表示用了 status 和 type(比如 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 BY、DISTINCT、含子查询或 UNION 的场景,且无法通过索引消除中间结果集。
- 优先让
ORDER BY或GROUP BY的字段落在复合索引最右位置,例如查WHERE status = ? ORDER BY create_time,建INDEX(status, create_time) - 避免
SELECT *配合ORDER BY—— 如果只查几列,可建覆盖索引减少回表 -
Using temporary在GROUP BY时若字段无索引,建索引往往比加SQL_BIG_RESULT更有效
为什么 EXPLAIN 的 rows 估算值和实际扫描行数差距很大
rows 是优化器基于统计信息预估的扫描行数,并非精确值。当表数据分布不均、长期未 ANALYZE TABLE、或存在大量重复值时,估算容易严重失真。
例如某字段只有 'A'/'B' 两个值,但优化器误判为均匀分布,就可能选错索引甚至放弃使用索引。
- 执行
ANALYZE TABLE table_name更新统计信息(注意:会锁表,建议低峰期操作) - 用
SHOW INDEX FROM table_name查看Cardinality值,过低(如远小于总行数)说明统计不准 - 对倾斜字段(如状态字段 99% 是 'active'),考虑用条件拆分查询或添加高频值过滤提示
EXPLAIN 里没报错、没警告,但 rows 和 key_len 组合暴露出来的“看似走了索引,实则只擦边”的情况。










