必须手动输入explain format=traditional前缀分析慢查询,不可直接执行原sql;需替换参数、清理格式,并重点解读type、key、rows三列判断索引使用情况。

在 phpMyAdmin 里加 EXPLAIN 前缀必须手动输,不能点「执行」按钮
直接复制 Laravel 或业务代码里的 SQL 到 phpMyAdmin 的 SQL 标签页,然后点「执行」——这一步就错了。它真会去跑查询,可能改数据、锁表、拖慢整个库。正确做法是:在原 SQL 最前面手敲 EXPLAIN FORMAT=TRADITIONAL,再执行。
原因很简单:EXPLAIN ANALYZE 虽然能显示真实执行耗时,但 phpMyAdmin 对它的解析支持不稳定,常报语法错误或返回空结果;FORMAT=TRADITIONAL 是兼容性最稳的输出格式,字段含义清晰,适合快速判断瓶颈。
- 别写
EXPLAIN SELECT * FROM users WHERE ...—— 缺少 FORMAT 容易被 phpMyAdmin 当成旧版语法处理 - 如果 SQL 带参数占位符(如
?或:id),先替换成具体值再加EXPLAIN,否则解析失败 - Laravel 日志里捞出的 SQL 可能含反引号和换行,粘贴后建议用 phpMyAdmin 的「格式化」按钮清理一下,避免语法误判
看懂 EXPLAIN 输出里最关键的三列:type、key、rows
执行完 EXPLAIN 后,重点盯住这三列,它们直接暴露索引是否生效:
-
type是连接类型:出现ALL就是全表扫描,基本等于没走索引;range或ref才算合理;const最理想(主键/唯一索引等值查询) -
key显示实际用的索引名:为空表示完全没走索引;若显示了索引但rows很大,说明索引区分度低或查询条件没命中索引最左前缀 -
rows是预估扫描行数:不是结果集大小,而是 MySQL 认为要读多少行才能拿到结果;从 10 万跳到 500 万,性能通常断崖下跌
例如 EXPLAIN SELECT * FROM orders WHERE status = 1 AND created_at > '2026-04-01' 返回 type=ALL 且 key=NULL,说明 status 和 created_at 都没被索引覆盖,得建复合索引。
建索引前先确认 WHERE 条件顺序和函数使用
MySQL 复合索引遵循最左前缀原则,但很多人建完发现 EXPLAIN 还是不走索引,问题常出在这两处:
- WHERE 中字段顺序和索引定义顺序不一致:比如索引是
(user_id, status),但 SQL 写成WHERE status = 1 AND user_id = 123,MySQL 仍能用上,但若写成WHERE status = 1单独查,就完全失效 - 在索引列上用了函数或表达式:
WHERE DATE(created_at) = '2026-09-14'会让created_at索引彻底失效;应改写为WHERE created_at >= '2026-09-14 00:00:00' AND created_at - 隐式类型转换也会让索引失效:比如字段是
VARCHAR,但查询写成WHERE mobile = 13800138000(没加引号),MySQL 会转成数字比对,索引失效
Extra 字段里出现 Using filesort 或 Using temporary 就得警惕
这两项不是报错,但意味着 MySQL 在内存或磁盘上额外做了排序或临时表操作,尤其是数据量上来后性能雪崩明显:
-
Using filesort:ORDER BY 字段没被索引覆盖,或索引顺序和排序需求不一致(比如索引是(a,b),但 ORDER BY b,a) -
Using temporary:常见于 GROUP BY、DISTINCT、子查询转 JOIN 后没走索引,或 UNION 查询没优化好 - 解决思路不是硬加索引,而是先看能否重写 SQL:比如把
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2)改成LEFT JOIN,往往比加索引更有效
真正容易被忽略的是:phpMyAdmin 的「Profiling」功能(SQL 执行页面右上角开关)。开启后能精确看到哪一步耗时最长,比如卡在 Sending data 阶段,大概率是结果集太大或网络慢,跟索引关系不大——这时候该查应用层分页逻辑,而不是猛建索引。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











