行数估算和成本分析是判断SQL查询性能瓶颈最直接依据;需对比预估Rows与实际Rows识别统计信息缺失、隐式转换等问题,结合Cost占比定位热点操作,并用EXPLAIN ANALYZE交叉验证。

SQL执行计划里的行数估算和成本分析,是判断查询性能瓶颈最直接的依据。准确理解这两项指标,能快速识别是否走错索引、是否缺少统计信息、是否存在隐式转换等问题。
看行数估算:先盯“Rows”列,再比对实际返回
执行计划中每个操作节点的“Rows”值(或“Cardinality”),代表优化器预估该步骤将输出的行数。这个数字是否合理,直接反映统计信息质量与估算逻辑的可靠性。
- 若某张表的Rows远小于实际数据量(比如预估1行,实际扫描10万行),大概率是缺失统计信息或直方图不准,需运行 ANALYZE TABLE 或更新统计信息
- 若连接后Rows突增数十倍(如两张各1万行的表关联后预估1亿行),说明连接条件选择性被严重低估,可能因字段无索引、存在函数/类型转换,或多列关联缺乏联合统计信息
- 聚合(GROUP BY)或排序(ORDER BY)前的Rows明显偏高,常意味着过滤条件没下推到位,可检查WHERE是否写在正确位置、是否被子查询或视图包裹导致延迟下推
看成本(Cost):不是绝对值,而是相对权重参考
Cost是优化器内部计算出的资源开销估算,单位无意义,但同一计划中各步骤的Cost比例极具诊断价值。高Cost节点往往是性能热点。
- 某张表全表扫描(Seq Scan)的Cost占比超70%,而它本应走索引,优先检查该字段是否有可用索引、索引是否失效(如前导列未出现在WHERE中)、是否因类型不匹配导致索引跳过
- Nested Loop成本异常高,通常因内表未走索引或驱动表返回行数远超预期——此时应先压降驱动表的Rows,再确认内表连接字段是否有高效索引
- Hash Join的Cost包含build和probe两阶段,若build阶段Cost陡增,说明右表过大或内存不足(work_mem太小),可能触发磁盘哈希,需调大work_mem或改用Merge Join
交叉验证:用EXPLAIN ANALYZE看真实行为
仅看预估(EXPLAIN)容易误判。务必结合 EXPLAIN ANALYZE,对比“Rows”(预估)和“Actual Rows”(实际),关注差异倍数。
- 预估100行,实际10万行 → 误差1000倍,统计信息严重滞后,立即更新
- 预估与实际接近,但执行时间长 → 问题不在估算,而在IO、锁、并发或硬件层面(如磁盘慢、buffer命中率低)
- 某节点Actual Rows为0,但Cost不为0 → 该分支被提前剪枝(如index condition过滤掉全部数据),属正常优化,不必干预
辅助线索:留意Warnings和Hint提示
部分数据库(如PostgreSQL 12+、MySQL 8.0优化器跟踪)会在执行计划末尾附带Warning,例如:
- "missing statistics for column 'status'" → 直接定位统计缺失字段
- "type mismatch: comparing text to varchar" → 隐式转换导致索引失效
- "planner chose generic plan after 5 executions" → 参数化查询触发了计划缓存泛化,需考虑使用pg_hint_plan或重写逻辑










