Navicat中SQL Server图形化执行计划的“查询成本(相对于批处理)”是优化器估算的相对资源比重,非实际耗时;仅在多语句批处理中有比较意义,单语句恒为100%,且受统计信息准确性直接影响。
SQL Server 图形化计划里的「查询成本」是相对值,不是毫秒数
navicat 点“解释”后右上角显示的「查询成本(相对于批处理)」,比如 92%,指的是这条语句在当前批处理(batch)中所占的预估资源比重,不是执行耗时,也不是 cpu 占用百分比。它由 sql server 优化器基于统计信息和模型估算得出,仅用于横向比较同一批里各语句的开销权重。
常见误解是把它当“执行花了92%时间”,但实际可能整条语句只跑了 50ms,而另一条 INSERT 占了批处理里剩下的 8%,却耗时 2s——成本值不反映绝对性能。
- 批处理中只有一条语句时,成本恒为
100%,毫无参考价值 - 多语句批处理(如 BEGIN...END 块)里,成本才有对比意义;但 Navicat 默认单语句执行,你得手动拼成批处理才能看到相对分布
- 成本值受统计信息影响极大:若表数据已增删百万行但没更新统计信息,
Estimated Rows可能错得离谱,成本估算也会失真
MySQL 的 type 和 rows 比成本值更直接管用
MySQL 的 EXPLAIN 输出里根本没有“cost”列(除非你用 EXPLAIN FORMAT=JSON 并手动解析 cost_info 字段),Navicat 默认展示的是传统格式,真正该盯的是 type 和 rows:
-
type=ALL+rows=124893→ 全表扫描,且预计读 12 万行,基本等于没走索引 -
type=ref+rows=2→ 用上了非唯一索引,只查 2 行,健康 -
key=NULL→ 优化器明确放弃所有索引,哪怕表上有 5 个索引也白搭
注意:rows 是预估行数,不是真实返回数;真实行数得看 EXPLAIN FORMAT=JSON 里的 rows_examined_per_scan,或 PostgreSQL 的 EXPLAIN (ANALYZE) 中的 actual rows。
PostgreSQL 的 cost 是两阶段估算,需结合 buffers 和 timing 看
PostgreSQL 的 EXPLAIN 默认输出里有 cost=123.45..567.89,这是两段式:前段是启动成本(startup cost),后段是总成本(total cost),单位是“磁盘页读取代价”,不是时间。但 Navicat 默认只发 EXPLAIN,不带 ANALYZE,所以你看到的只是理论模型估算,和真实执行差距可能很大。
- 想看真实耗时?必须手动改成
EXPLAIN (ANALYZE, BUFFERS, TIMING) - 如果
Buffers: shared hit=12345很高,说明缓存命中差,I/O 压力大;Execution Time: 42.123 ms才是真实耗时 - Navicat 查询窗口顶部状态栏显示的“耗时”是客户端往返时间,包含网络延迟、结果集序列化等,不能替代数据库内实际执行时间
别信单一数值,重点看运算符之间的数据流
成本值或 cost 数字本身容易误导,真正暴露问题的是图形化计划里节点间的连接形态:
- 箭头极粗(比如从
SELECT直连到Clustered Index Scan)→ 中间传递行数爆炸,大概率 WHERE 条件失效或索引未覆盖 - 出现红色虚线框标注“缺少索引建议”→ Navicat 提示的
CREATE INDEX语句只是单列建议,得人工核对是否已有更优的复合索引 - 并行线程数(
Parallelism运算符)频繁出现 → 说明查询本身够重,但若搭配低效的Hash Match或大量Sort,反而拖慢整体
最常被忽略的是:图形化计划里 Actual Rows 和 Estimated Rows 差异超过 10 倍,就该立刻跑 UPDATE STATISTICS 或 ANALYZE table_name,否则所有成本估算都建立在错误前提上。











