Oracle执行计划中cardinality与cost的计算逻辑是什么?
Oracle执行计划Cardinality与Cost计算逻辑说明
基数(Cardinality)1513的计算逻辑
基数是Oracle成本优化器(CBO)估算的当前执行步骤返回的行数,你的场景计算逻辑符合CBO的默认规则:
- 你的查询条件使用了
SUBSTR(activity,1,2) = '49',属于对列施加函数运算的场景,如果你没有额外收集对应扩展统计信息、也没有建基于该函数的索引、同时activity列没有收集直方图的话,CBO无法准确判断该条件的匹配率,会使用硬编码的1%默认选择率做估算。 - 1513等于
friends表的统计总行数 * 1% 后四舍五入的结果,你可以通过SELECT NUM_ROWS FROM USER_TABLES WHERE TABLE_NAME = 'FRIENDS';查询表的统计行数,乘以0.01后即可验证匹配。
成本(Cost)1302的计算逻辑
成本是CBO对执行语句需要消耗的IO、CPU资源的加权折算值,默认以单块随机读的耗时作为单位:
- 你的语句未命中索引,会走全表扫描,成本核心构成是读取整张表所有数据块的IO开销,叠加CPU过滤每行数据的开销折算值。
- 1302基本和
friends表占用的实际数据块数接近,你可以通过SELECT BLOCKS FROM USER_TABLES WHERE TABLE_NAME = 'FRIENDS';查询表占用块数,该值和1302的差值来自多块读参数、CPU开销折算的微调。
复现计算结果的方法
你可以通过以下SQL直接复现执行计划显示的两个值:
-- 生成执行计划 EXPLAIN PLAN FOR SELECT * FROM friends WHERE SUBSTR(activity,1,2) = '49'; -- 查询对应执行步骤的基数和成本 SELECT CARDINALITY, COST FROM PLAN_TABLE WHERE OPERATION = 'TABLE ACCESS' AND OBJECT_NAME = 'FRIENDS';
如果要验证估算逻辑是否正确,可以执行以下查询:
- 验证基数:
SELECT COUNT(*) FROM friends WHERE SUBSTR(activity,1,2) = '49';,如果该实际值和1513偏差很大,说明CBO估算不准,建议收集对应扩展统计信息或者创建函数索引优化。 - 验证成本:
SELECT BLOCKS FROM USER_TABLES WHERE TABLE_NAME = 'FRIENDS';,该值和1302的偏差属于CBO参数折算的正常范围。
内容的提问来源于stack exchange,提问作者Kuru
相关产品推荐
相关产品推荐

