mysql执行计划异常需先定位根源:统计信息不准、索引设计缺陷或查询写法误判;重点检查EXPLaiN的rows和key,运行ANALYZE table更新统计信息,用SHOW INDEX确认索引结构,结合EXPLAIN format=jsON分析成本,针对性优化索引顺序与查询写法,并通过EXPLAIN ANALYZE等持续验证效果。

MySQL执行计划异常,通常意味着优化器选择了非预期的索引、全表扫描、临时表或文件排序等低效路径,直接拖慢查询性能。核心思路不是“强行改SQL”,而是先定位偏差根源——是统计信息不准?索引设计缺陷?还是查询写法触发了优化器误判?
检查执行计划是否真实反映当前数据分布
EXPLAIN结果只是预估,可能和实际执行严重不符。重点看red”>rows列是否远大于实际匹配行数,key是否为NULL或使用了错误索引。
- 运行ANALYZE TABLE table_name;更新统计信息,尤其在大批量导入/删除后
- 用SHOW INDEX FROM table_name;确认索引字段顺序、是否包含常用过滤/排序列
- 对高频慢查询,用EXPLAIN FORMAT=json查看详细成本估算(如range_analysis、considered_execution_plans)
识别常见执行计划陷阱及对应修复
以下情况往往不是SQL本身问题,而是索引或数据结构不匹配:
- using filesort:ORDER BY未命中索引最左前缀,或存在范围条件+排序字段不连续(如WHERE a > 10 ORDER BY b,c)→ 调整索引顺序,或拆分查询
- Using temporary:GROUP BY/ORDER BY涉及多表、函数、不同字符集字段→ 检查是否能用覆盖索引避免临时表,或改写为子查询提前过滤
- type=ALL 或 type=index:无有效索引可用→ 确认WHERE条件字段是否有索引,注意隐式类型转换(如字符串字段用数字查询)会失效索引
- Extra: Using where; Using index:理想状态;但若出现Using where且key为空,说明索引未被用于过滤,仅用于回表→ 需补充过滤字段到索引中
针对性优化索引与查询写法
避免盲目加索引,优先保障高频查询路径:
- 复合索引遵循“过滤→排序→返回”顺序:WHERE条件字段(等值在前、范围在后)、ORDER BY字段、select需要的字段(覆盖索引)
- 慎用SELECT *,大字段(TEXT/BLOB)单独建表或延迟加载,减少回表开销
- 对IN列表过长(>300项)、OR条件复杂、模糊查询(LIKE ‘%abc’)等场景,考虑改用全文索引、ES或冗余字段预计算
- 分页深度过大(OFFSET 1000000)时,用游标分页(WHERE id > last_id LIMIT 20)替代LIMIT跳过
验证与持续监控
优化不是一次性的,需闭环验证效果:
- 用EXPLAIN ANALYZE(MySQL 8.0.18+)对比优化前后真实执行耗时与行数
- 开启slow_query_log并设置long_query_time=0.1捕获准慢查询
- 定期用sys.schema_unused_indexes视图清理长期未使用的索引,降低维护开销
- 对核心业务表,建立performance_schema监控关键指标(如rows_examined、sort_merge_passes)