SQL 执行慢?别急着加索引,先看 Explain 执行计划

发布时间:2026/5/30 19:15:23

SQL 执行慢?别急着加索引,先看 Explain 执行计划 SQL 执行慢别急着加索引先看 Explain 执行计划慢 SQL 不是玄学。每条慢查询背后都有一个明确的罪魁祸首。而找出它的第一步不是改代码是执行一句EXPLAIN。先学会看这张表执行EXPLAIN SELECT ...你会得到一张结果表。只看这几列就够了列名含义什么值是好的type访问类型决定了查询方式consteq_refrefrangeindexALLkey实际用了哪个索引有索引名别是NULLrows扫描了多少行越少越好Extra额外信息藏着很多坑见下文详解一、type最关键的一列它直接告诉你数据库是怎么找数据的。从好到差排个序type含义评价system只有一行表只有一条记录极好几乎不会慢const主键或唯一索引等值查询极好一步到位eq_ref唯一索引关联查询很好ref非唯一索引等值查询良好大多数场景够用range索引范围扫描BETWEEN、、IN可接受index全索引扫描不回表数据量小可以大了就慢ALL全表扫描这就是慢的根源一句话type到达ALL说明没用索引优先优化这里。二、rows扫描了多少行这个数字越小越好。rows 1精准命中完美。rows 几百还行看场景。rows 几万/几十万大概率要出问题。关键对比rows 10, 实际返回 10 行 → 健康 rows 100000, 实际返回 1 行 → 严重浪费索引没选对扫描行数和返回行数差距越大说明索引越没用到位。三、Extra最容易忽略的暗号这一列藏着真正的排查线索。值含义怎么处理Using index覆盖索引不用回表✅ 最佳状态不用改Using where存储引擎层过滤后Server 层还要再过滤⚠️ 索引不够精准Using index condition索引下推ICP5.6 支持✅ 还不错Using filesort需要额外排序没用上索引排序❌ 加索引或改ORDER BYUsing temporary用了临时表常见于GROUP BY/DISTINCT❌ 优化分组逻辑或加索引Using join buffer用了 Join Buffer没走索引关联❌ 被驱动表没索引补上出现Using filesort或Using temporary90% 的情况是索引没建对。四、实战一条慢 SQL 怎么拆假设这条 SQL 跑了 8 秒sqlSELECT u.name, o.amount FROM users u JOIN orders o ON u.id o.user_id WHERE o.created_at 2026-01-01 ORDER BY o.amount DESC LIMIT 10;执行EXPLAIN结果idselect_typetabletypekeyrowsExtra1SIMPLEoALLNULL500000Using where; Using filesort1SIMPLEueq_refPRIMARY1—诊断orders表type ALL全表扫描 50 万行 →没用索引。Extra Using filesort排序没用上索引 →ORDER BY没索引支撑。优化sql-- 给 orders 表加联合索引 ALTER TABLE orders ADD INDEX idx_created_amount (created_at, amount DESC);再看EXPLAINtabletypekeyrowsExtraorangeidx_created_amount320Using index conditionueq_refPRIMARY1—type从ALL变成range。rows从 50 万降到 320。Extra出现Using index condition不再filesort。8 秒 → 0.01 秒就改了一个索引。五、排查流程记住这条链路SQL 慢 └─ EXPLAIN 看 type ├─ type ALL → 没走索引查 key 列补索引 ├─ type index → 全索引扫描看是否需要回表 └─ type 够好但仍慢 → 看 rows 和 Extra ├─ Using filesort → ORDER BY 没索引 ├─ Using temporary → GROUP BY 没索引 └─ Using join buffer → 被驱动表缺索引最后一句话慢 SQL 的答案80% 藏在EXPLAIN的type和Extra里。先看执行计划再动手改别上来就加索引。

相关新闻