Query took数值最可靠,它反映客户端真实耗时,含网络、执行与结果组装全过程;但须结合EXPLAIN中type、key、rows、Extra四列变化判断优化本质,且关注Rows_examined/Rows_sent比值是否显著下降。
直接看底部“Query took”数值最可靠
navicat 执行完一条 sql 后,结果窗口底部会自动显示 query took x.xxx sec,这个时间是客户端真实感知的耗时,包含网络传输、服务端执行、结果集组装全过程。它不是估算值,也不依赖数据库内部计时器,适合做前后对比。
注意:不要依赖“Messages”面板里 set statistics time on 输出的 CPU 时间——那是 SQL Server 特有机制,MySQL/PostgreSQL 不支持;Navicat 本身也不解析这类输出。
- 每次测试前手动清空查询结果窗口,避免误读上一次残留的耗时
- 同一语句至少执行 3 次,取中间值(排除首次缓存加载或临时抖动)
- 确保两次测试间没有其他写操作干扰(如大事务未提交),否则
Rows_examined可能失真
用 EXPLAIN 对比执行计划差异更关键
光看 Query took 只能知道“快了没”,但不知道“为什么快”。真正决定优化是否落地的,是执行计划里的 type、key、rows 和 Extra 四列变化。
- 优化前
type = ALL,优化后变成type = ref→ 索引生效了 - 优化前
key = NULL,优化后key = idx_status_time→ 真正用了索引 - 优化前
rows = 482916,优化后rows = 127→ 扫描行数下降 3800 倍 - 优化前
Extra含Using filesort,优化后消失 → 排序走索引了
避免被“缓存”误导的实操细节
MySQL 的查询缓存(Query Cache)在 8.0 已移除,但 InnoDB 缓冲池(Buffer Pool)和操作系统页缓存仍会影响第二次执行时间。如果你发现优化后第一次跑得慢、第二次突飞猛进,大概率是数据页刚被载入内存。
- 测试前先执行
SELECT SLEEP(1)触发连接复用,避免新建连接开销干扰 - 对大表测试,可在优化前后分别执行
SELECT COUNT(*) FROM table_name预热缓冲池(但别在生产环境乱跑) - 若需彻底排除缓存影响,可临时加
SQL_NO_CACHE(MySQL 5.7 及以前)或用RESET QUERY CACHE(已废弃,仅作了解)
别只信单次执行时间,盯住 rows_examined / rows_sent 比值
执行时间会受网络、瞬时负载干扰,但 Rows_examined(扫描行数)和 Rows_sent(返回行数)的比值,暴露的是 SQL 本身的效率缺陷。这个比值 > 100 就该警惕,> 1000 基本等于索引没建对或写法踩坑。
比如 DELETE FROM logs WHERE created_at 返回 <code>Rows_sent = 0,但 Rows_examined = 2.3M —— 这说明删得再干净,也扫了全部 230 万行。这时候加索引或改成分批删,比调 timeout 有用得多。











