slow_query_log 里看不到没走索引的查询,因为该日志仅记录执行时间超阈值的语句,而小表未走索引的查询可能极快(如0.002秒),不满足慢查条件;真正需定位的是“本该走索引却未走”的低效查询。
为什么 slow_query_log 里看不到没走索引的查询
因为 mysql 的 slow_query_log 只记录执行时间超阈值的语句,而一个没走索引的 select 如果表很小(比如几百行),可能 0.002 秒就返回了,根本进不了慢日志。你真正想抓的,是“本该走索引却没走”的查询,不是“跑得慢的查询”。
phpMyAdmin 本身不主动捕获或标记未使用索引的查询,它只是个 SQL 执行界面。但你可以借助它的两个隐藏能力:SQL 分析器 + 查询执行计划查看,再配合 MySQL 的 EXPLAIN 和状态变量,反向定位问题语句。
在 phpMyAdmin 里直接看 EXPLAIN 结果
把可疑的 SELECT 语句粘贴到 phpMyAdmin 的 SQL 标签页,**不要点“执行”**,先在语句前加 EXPLAIN,比如:
EXPLAIN SELECT * FROM users WHERE name = 'alice';
执行后看结果中的 type 和 key 列:
-
type是ALL或index→ 全表扫描或全索引扫描,大概率没走有效索引 -
key是NULL→ 明确没用任何索引 -
rows值远大于实际匹配行数 → 索引选择性差或没被选中
注意:phpMyAdmin 对 EXPLAIN FORMAT=JSON 支持有限,建议用默认表格格式;如果字段太多看不清,可加 EXPLAIN EXTENDED 后跟 SHOW WARNINGS 查看优化器重写后的语句。
用 phpMyAdmin 查看 session 级索引未命中统计
MySQL 会记录当前连接中因缺失索引导致的临时表/文件排序次数,这些指标比慢日志更敏感。在 phpMyAdmin 中执行:
SHOW STATUS LIKE 'Handler_read%';
重点关注这几个值(执行完你的查询后再查一次,做差值):
-
Handler_read_first高 → 扫描了索引首个 entry,但未必是好信号(可能配合Handler_read_next大量递增) -
Handler_read_rnd_next显著上升 → 发生了基于随机主键回表或文件排序,通常意味着缺失覆盖索引或ORDER BY没走索引 -
Handler_read_all上升 → 全表扫描发生
这个方法需要你在 phpMyAdmin 中手动比对前后状态,不能自动告警,但它能暴露那些“快但错”的查询。
导出查询并用 pt-query-digest 分析(绕过 phpMyAdmin 局限)
phpMyAdmin 没有查询采样功能,但你可以让它帮你生成可分析的原始数据:
- 开启 MySQL 的通用查询日志:
SET GLOBAL general_log = 'ON'; SET GLOBAL log_output = 'TABLE'; - 在 phpMyAdmin 中执行一批业务操作(比如打开某个列表页、提交表单)
- 回到 phpMyAdmin,查
mysql.general_log表,导出为 CSV - 本地用
pt-query-digest分析(需 Perl 环境):pt-query-digest --filter '$event->{Bytes} > 1024' general_log.csv
输出里会标出 Rows_examined 远高于 Rows_sent 的语句——这就是典型未用索引的候选者。phpMyAdmin 在这里只充当日志查看和导出工具,真正的分析得靠外部工具。
真正难的不是看到 key: NULL,而是判断“为什么优化器放弃已有索引”:可能是统计信息过期、WHERE 条件含函数、字符集不匹配,或者 MySQL 认为走索引还不如扫表。这些得结合 SHOW INDEX FROM table 和 ANALYZE TABLE 综合看,phpMyAdmin 只能给你第一层线索。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











