Navicat 不计算 Cost 值,仅原样展示后端数据库优化器生成的估算结果;MySQL 的 cost 是归一化相对权重,Oracle 依赖 I/O 与 CPU 参数公式,SQL Server 的 Query cost 是批内相对百分比,PostgreSQL 默认 EXPLAIN 仅为静态预估,真实耗时需用 EXPLAIN ANALYZE 获取。

Navicat 里的 Cost 值不是它算的,只是照搬数据库给的
Navicat 本身不参与 Cost 计算,它只是把 MySQL、Oracle 或 SQL Server 优化器生成的 COST 字段原样展示出来。你看到的那个数字,完全取决于后端数据库引擎——MySQL 的归一化估算、Oracle 的 I/O+CPU 公式、SQL Server 的 Query cost(relative to batch),三者算法不同、单位不同、甚至物理意义都不同。
常见误解是拿 Navicat 里两个不同库的 Cost 值直接对比,或者以为“Cost 越小越好”就一定成立。其实:MySQL 的 cost_info.total_cost 是相对权重,Oracle 的 COST 依赖 sreadtim 等参数是否准确,SQL Server 的右上角百分比(Query cost (relative to batch))只在同一批语句中可比。
MySQL 的 Cost 值怎么看才不被误导?
MySQL 8.0+ 的 Cost 来自基于成本的优化器(CBO),但它的估算严重依赖统计信息是否新鲜。如果表长期没执行过 ANALYZE TABLE,CARDINALITY 过时,Cost 就是拍脑袋值,可能和实际执行天差地别。
-
read_cost:读页开销,受innodb_page_size、缓冲池命中率影响 -
eval_cost:每行 CPU 运算开销,跟 WHERE 中函数、类型转换强相关 - 总 Cost =
read_cost + eval_cost + sort_cost + tmp_table_cost等子项之和 - 想看明细?必须用
EXPLAIN FORMAT=JSON SELECT ...,Navicat GUI 默认只显示汇总列
SQL Server 图形计划里的 “Query cost” 到底指什么?
这个值出现在图形化执行计划右上角,全称是 Query cost (relative to batch),意思是“该语句占整批(batch)资源消耗的百分比”。它不是绝对耗时,也不是 IO 次数,而是一个由 SQL Server 优化器内部模型估算出的相对权重。
重点看三个信号:
- 超过
80%→ 这条语句吃掉了整批操作的大头,优先优化 - 红色虚线框运算符 → Navicat 提取的缺失索引建议,但仅基于单表 WHERE,不验证已有索引覆盖度
- 粗箭头 → 箭头越粗,中间传递的行数越多;若连着
Clustered Index Scan且极粗,基本等于全表扫描
注意:Navicat 默认获取的是 实际执行计划(actual execution plan),所以你会同时看到 Actual Rows 和 Estimated Rows。两者差距大(比如预估 1 行、实际扫 50 万行),第一反应不是改 SQL,而是跑 UPDATE STATISTICS。
PostgreSQL 的 Cost 完全不能信?
Navicat 点「解释」按钮默认只发 EXPLAIN,不是 EXPLAIN ANALYZE。这意味着你看到的所有 cost=0.29..8.30、rows=1 都是 planner 的静态预估,没跑 SQL,也没真实数据支撑。
要拿到真实 Cost,必须手动改写:
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;
但得小心:EXPLAIN ANALYZE 会真实执行语句——带 UPDATE、DELETE、或锁表逻辑的语句,千万别手滑点错。
PostgreSQL 的 Cost 单位是“顺序页读取代价”,默认 seq_page_cost = 1.0,但实际磁盘/SSD 性能差异会让这个归一化值失真。真正关键的不是 Cost 数字本身,而是 Actual Total Time 和 Buffers 统计。
Cost 值背后没有魔法,只有数据库引擎的估算模型 + 你本地的统计信息质量 + Navicat 的渲染能力。最常被忽略的,是把它当绝对指标去比大小,而不是结合 Actual Rows、Warnings、Memory Grant 一起交叉验证。


















