key_len 是什么
key_len 表示 EXPLAIN 输出中「本次实际使用到的索引字节数」。它是判断联合索引用到第几列的主要依据:把 key_len 与各列定义长度累加值对照,就能看出条件是否只命中了前缀列。计算与字符集强相关——utf8mb4 每字符 4 字节,varchar 还要额外算长度字节,可空列再加 1 字节 null 标志。
基本信息
| 适用版本 | MySQL 5.7 / 8.0 |
|---|---|
| 输出位置 | EXPLAIN 的 key_len 列(命中索引时才有值) |
| utf8mb4 char(10) | 40 字节(NOT NULL) |
| utf8mb4 varchar(20) | 约 82 字节(4×20 + 2 长度字节) |
| 可空列 | 在基础上再加 1 字节 null 标志 |
| 数值类型 | BIGINT 8 字节、INT 4 字节、TINYINT 1 字节 |
典型使用场景
- 验证联合索引是否被完整使用:条件是否只吃到了第一列
- 排查「索引建了但慢」:确认第二、第三列条件是否参与索引定位
- 设计联合索引顺序:按实际查询条件的使用频率决定列序
- 对比优化前后效果:调整 SQL 或索引后 key_len 是否变大
- 评审他人提交的 SQL:判断新增条件是否真的用上了索引
反推示例
反推示例
-- 假设索引为 idx(user_id, status, created_at)
EXPLAIN SELECT * FROM appdb.orders
WHERE user_id = 1 AND status = 2;
-- key_len 只覆盖 user_id + status 的长度,说明第三列未参与索引定位
-- 若 key_len 等于三列总长,说明三列都用上了(第三列可能用于范围或排序)
-- 对照脚本:把索引列定义长度相加,与实际 key_len 比较
SELECT column_name, column_type, is_nullable, character_set_name
FROM information_schema.columns
WHERE table_schema = 'appdb' AND table_name = 'orders'
AND column_name IN ('user_id','status','created_at');常见类型长度对照
| 列定义 | 字符集 | key_len 参考值 |
|---|---|---|
| INT NOT NULL | 无 | 4 字节 |
| BIGINT NOT NULL | 无 | 8 字节 |
| char(10) NOT NULL | utf8mb4 | 40 字节(10×4) |
| varchar(20) NOT NULL | utf8mb4 | 82 字节(20×4+2) |
| varchar(20) NULL | utf8mb4 | 83 字节(再加 1 字节 null 标志) |
key_len 只说明用了几列、用了多少字节,不区分这些字节是用于等值查找、范围扫描还是排序;判断排序开销还要看 Extra 里是否出现 Using filesort。对比不同环境的数字前,务必先记录字符集、版本与列定义,否则数字无法复用。
对比 key_len 前必须确认库的字符集:同一列在 utf8mb3(3 字节/字符)与 utf8mb4(4 字节/字符)下 key_len 完全不同,拿不同环境的数字对比会得出完全错误的结论。