explain分析慢sql需聚焦rows、key_len与extra的组合信号:rows远超返回行数表明索引未走对或统计过期;key_len小于联合索引总长提示最左前缀缺失;extra含using filesort/temporary说明排序分组未覆盖;filtered过低反映where条件选择性差;key=null多因函数操作或隐式转换导致索引被弃用。

直接在慢 SQL 前加 EXPLAIN 就能看到执行计划,但关键不是“有没有走索引”,而是看几处组合信号——它们往往比 type=ALL 更早暴露真实瓶颈。
重点盯住 rows、key_len 和 Extra 的配合关系
单看某一项容易误判,要交叉验证:
-
rows 远大于实际返回行数(比如查10条却预估扫5万行)→ 索引没走对,或表统计信息过期,可运行
ANALYZE TABLE 表名更新 - key 显示用了索引,但 key_len 明显偏小(如三列联合索引总长200,key_len 只有76)→ 最左前缀条件缺失,检查 WHERE 中是否漏了第一列或第二列的等值条件
- Extra 出现 Using filesort 或 Using temporary → ORDER BY 或 GROUP BY 字段不在索引中,或顺序不匹配;覆盖索引需包含 SELECT 字段 + WHERE 条件字段 + 排序/分组字段
filtered 值低说明 WHERE 条件本身有问题
哪怕 key 和 type 都正常,如果 filtered ≈ 1.00(即1%),意味着索引选出了10万行,但只有1000行满足 WHERE 条件。这时加索引意义不大,应考虑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 拆分查询:把高选择性条件(如 status='paid')和低选择性条件(如 created_at > '2024-01-01')分开处理
- 改写逻辑:用 EXISTS 替代 IN 子查询,或把模糊匹配(LIKE '%关键词%')移到应用层过滤
- 补充冗余字段:如把日期范围 + 状态合并为生成式字段(status_date),再建索引
key=NULL 不等于没建索引,而是优化器主动弃用
常见原因有:
- 在索引列上用了函数:
WHERE DATE(create_time) = '2024-01-01'→ 改成WHERE create_time >= '2024-01-01' AND create_time - 隐式类型转换:
user_id VARCHAR(32)却写WHERE user_id = 123→ 改成WHERE user_id = '123' - OR 条件中部分分支无索引:
WHERE a=1 OR b=2,若 b 列无索引,可能全表扫描;可拆成 UNION ALL
复杂 SQL 用 FORMAT=JSON 挖更深线索
标准 EXPLAIN 表格不够细时,用 EXPLAIN FORMAT=JSON 查:
- used_columns:确认哪些列真正参与索引查找,哪些只是 Server 层过滤
- pushed_condition:没下推到引擎层的条件,会额外增加 CPU 和内存开销
- range_analysis:列出优化器评估过但拒绝的其他索引方案及原因,比如“索引区分度太低”










