Cost是优化器基于统计信息估算的相对开销值,非真实耗时,不可跨语句或跨库比较;其本质是无量纲数值,涵盖CPU、IO及部分场景的网络开销,仅在同一计划内具可比性。

SQL执行计划中的Cost值,是优化器基于统计信息估算出的执行开销,并非真实耗时,也不能直接跨库或跨语句比较。它反映的是相对代价,核心作用是帮优化器在多个可行路径中选出“预计最省资源”的那个计划。
Cost值的本质:估算模型的输出结果
Cost不是秒数、不是IO次数,而是优化器内部成本模型计算出的一个无量纲数值。不同数据库(Oracle、PostgreSQL、SQL Server)的模型细节不同,但基本都包含三类开销估算:
- CPU Cost:如排序、哈希计算、表达式求值等消耗的CPU资源
- IO Cost:主要来自数据页读取(逻辑读/物理读),受表大小、索引选择性、缓存命中率影响较大
- Network Cost(部分引擎):分布式查询中数据传输的估算开销
注意:Cost只在同一个执行计划内具有可比性。比如某节点Cost=1000,其子节点Cost=800,说明该节点本身预估开销约200;但不能说Cost=500的SQL一定比Cost=5000的快——统计不准、绑定变量窥探、实际数据分布偏移都会让估算严重失真。
怎么看Cost:盯住“高占比+不合理”节点
真正要关注的不是总Cost数字,而是执行计划中Cost占比高、且与操作意图明显不符的节点。例如:
- 本应走索引却显示Index Scan Cost远高于Seq Scan → 可能统计信息过期,或索引字段选择性差
- Nested Loop外层返回10行,内层却预估每次查10万行 → 实际可能触发100万次单行回表,Cost虚低(因未准确估算回表放大效应)
- Hash Join Build侧Cost异常高,且Estimated Rows远小于实际 → 哈希表内存不足导致落盘,Cost模型未充分计入磁盘溢写代价
验证Cost是否靠谱:必须结合实际指标
仅看Cost容易误判。务必交叉验证以下三项:
- Actual Rows vs Estimated Rows:差异超一个数量级,说明统计信息失效,Cost失去参考价值
- Buffers / I/O Read Count(如EXPLAIN (ANALYZE)输出):真实逻辑读/物理读是否与IO Cost趋势一致
- Execution Time Breakdown:用pg_stat_statements或SQL Trace看各阶段真实耗时,确认瓶颈是否落在Cost最高的步骤上
若发现Cost低的操作实际最慢,大概率是成本模型未覆盖某些开销(如锁等待、大对象处理、函数调用开销),此时需绕过Cost,直接优化访问路径或数据分布。
调优时别迷信Cost:优先保证执行路径合理
比起把Cost从10000降到9500,更关键的是确保走了正确的路:
- 加索引前先确认WHERE条件和JOIN列是否被有效覆盖
- 改写SQL时避免隐式类型转换、函数包裹索引字段等导致索引失效的行为
- 对大表JOIN,优先考虑驱动表顺序、是否可用Merge/Hash替代Nested Loop
- 定期执行ANALYZE(PostgreSQL)或DBMS_STATS.GATHER_TABLE_STATS(Oracle)更新统计信息
Cost只是辅助判断工具,不是优化目标。路径对了,Cost自然会降;路径错了,再低的Cost也换不来性能提升。










