MySQL EXPLAIN 执行计划完全解读看懂这张表慢查询无处遁形在日常开发中SQL 写完能跑就行的心态往往是线上慢查询的根源。EXPLAIN 是 MySQL 自带的执行计划分析工具花 5 分钟看懂它能帮你提前拦截 80% 的性能问题。基本用法EXPLAINSELECT*FROMordersWHEREuser_id1001;在任意 SELECT 语句前加上EXPLAINMySQL 就会返回这条语句的执行计划而不会真正执行查询。核心字段解读执行计划返回一张表每个字段含义如下1. type最重要表示 MySQL 找到目标行的方式性能从好到差依次是type 值含义是否需要优化system表只有一行不需要const主键或唯一索引等值查询不需要eq_ref联表时使用主键/唯一索引不需要ref普通索引等值查询一般可接受range索引范围查询注意数据量index全索引扫描需要关注ALL全表扫描必须优化线上生产环境出现ALL或index就需要立刻排查。2. key实际使用的索引名称。如果是NULL说明没有走索引基本等同于全表扫描。-- 示例查看是否走了 idx_user_id 索引EXPLAINSELECT*FROMordersWHEREuser_id1001;-- 结果中 key idx_user_id 说明走了索引-- 结果中 key NULL 说明没走索引需要检查3. rowsMySQL 预估需要扫描的行数。这个数字越大查询越慢。对于千万级大表rows 超过 100 万就需要警惕超过 1000 万基本是灾难。4. Extra重要附加信息几个常见值Extra 值含义Using index覆盖索引性能最好Using where在存储引擎层过滤后还需要在 Server 层过滤Using filesort需要额外排序性能差Using temporary使用了临时表性能差出现Using filesort或Using temporary通常意味着 ORDER BY 或 GROUP BY 没有走索引。5. possible_keys vs keypossible_keysMySQL 认为可以用的索引keyMySQL 实际选择的索引两者不一致时说明 MySQL 的优化器放弃了某些索引需要分析原因必要时用FORCE INDEX强制指定。实战案例场景订单表 1000 万行按用户 ID 查最近订单很慢-- 问题 SQLSELECT*FROMordersWHEREuser_id1001ORDERBYcreated_atDESCLIMIT10;-- 执行 EXPLAINEXPLAINSELECT*FROMordersWHEREuser_id1001ORDERBYcreated_atDESCLIMIT10;执行计划显示type ALL全表扫描Extra Using filesort额外排序rows 9800000扫描近千万行优化方案建立联合索引ALTERTABLEordersADDINDEXidx_user_created(user_id,created_at);再次 EXPLAIN 后type refExtra Using indexrows 23只扫描 23 行查询时间从 4.2s 降到 0.003s。EXPLAIN ANALYZEMySQL 8.0MySQL 8.0 引入了EXPLAIN ANALYZE会真实执行查询并返回实际耗时比普通 EXPLAIN 更准确EXPLAINANALYZESELECT*FROMordersWHEREuser_id1001;输出中会包含每个步骤的实际执行时间和扫描行数方便定位瓶颈在哪一步。小结看 EXPLAIN 的优先级顺序先看type有没有全表扫描再看key走没走索引看rows扫描行数是否合理最后看Extra有没有 filesort 或 temporary养成每写一条复杂 SQL 就跑一次 EXPLAIN 的习惯大部分慢查询问题在上线前就能被发现。