最直接、最可靠的执行时间是结果窗口底部的“query took x.xxx sec”,它反映客户端真实感知的端到端耗时,含网络、执行与结果组装全过程;但需结合explain的type、key、rows、extra及rows_examined/rows_sent比值综合判断优化本质。
navicat 里最直接、最可靠的执行时间,就是结果窗口底部显示的 query took x.xxx sec ——它反映的是你真实感知到的端到端耗时,不是估算值,也不依赖数据库内部计时器。
怎么看 Query took 这个数值
执行任意 SQL 后,Navicat 会在结果表格下方自动显示一行信息,形如:Query took 0.248 sec。这个时间包含:客户端发请求 → 网络传输 → 服务端执行 → 结果组装 → 回传 → 渲染完成 全流程。
- 别去 Messages 面板找类似
CPU time = 15ms的输出——那是 SQL Server 的SET STATISTICS TIME ON机制,MySQL/PostgreSQL 不支持,Navicat 也不会解析它 - 每次测试前手动清空结果窗口,避免误把上一条语句的耗时当成本次结果
- 同一语句至少跑 3 次,取中间值;首次执行常因缓存未热导致偏高,第三次更接近稳定态
为什么不能只信 Query took
它告诉你“快了没”,但不解释“为什么快”。比如优化后 Query took 从 1.2s 降到 0.08s,看起来很好,但如果背后是 Rows_examined 从 500 万掉到 500,说明索引真生效了;要是只降到 490 万,那大概率只是碰巧命中了 Buffer Pool 缓存。
- 必须配合
EXPLAIN看type、key、rows、Extra四列变化 - 重点关注
Rows_examined / Rows_sent比值:> 100 就该警惕,> 1000 基本等于 SQL 或索引写错了 - MySQL 8.0 已移除 Query Cache,但 InnoDB Buffer Pool 和 OS Page Cache 仍会让第二次执行突飞猛进——这不是优化成果,是干扰项
如何排除缓存干扰做公平对比
想确认优化是否真的减少了扫描量,得让两次测试尽量在相同数据热度下进行,否则 Query took 会失真。
- 执行前先运行
SELECT SLEEP(1),等上一轮缓存效应衰减(简单但有效) - 对 MySQL,可加
SQL_NO_CACHE(仅限 5.7 及以前),如:SELECT SQL_NO_CACHE * FROM orders WHERE status = 'paid' - 确保两次测试之间没有大事务未提交,否则
Rows_examined可能被 MVCC 快照拉高 - 如果用的是连接池(如 HikariCP),Navicat 自己的会话列表看不到应用侧执行的语句——这时得切到数据库侧开慢日志:
SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 0;
真正难的不是看到那个数字,而是判断这个数字到底代表什么。网络抖动、缓存预热、事务隔离级别、甚至 Navicat 自身的结果集渲染逻辑,都会悄悄改写你看到的 Query took。盯住 Rows_examined 和执行计划,比盯着毫秒数重要得多。











