Oracle嵌套循环连接内行源预估行数与预期不符问题咨询
核心原因:Oracle执行计划内行的预估行数规则和认知偏差
你对嵌套循环内行预估行数的原有认知存在偏差:Oracle执行计划中,嵌套循环内行的ROWS列展示的是单次调用该内行操作返回的总预估行数,而非单条ROWID/单条记录的返回行数,同时内行的调用次数由外层驱动源的关联键去重后的基数决定,不是外层的总输出行数。
结合测试场景拆解逻辑
- 先明确基础数据分布:你造数时每个p_id在C表中对应100条记录,统计信息收集后优化器已知该分布特征。
- 执行计划层级逻辑梳理:
- ID=3~4步从P表过滤得到2行符合
p_num=1的记录,每个记录对应唯一p_id,这是最外层驱动源。 - ID=2的嵌套循环:外层是2个P表行,内行是ID=5的索引范围扫描,每次传入1个p_id,返回该p_id对应的100个C表ROWID,所以单次调用ID=5返回100行,总调用2次,ID=2的总输出行数为2*100=200,和执行计划显示一致。
- ID=1的嵌套循环:这里优化器识别到ID=2输出的200条记录,本质上只有2个不同的p_id,对应的C表ROWID是按p_id分组的,所以内行ID=6的
table access by index ROWID操作只会被调用2次,每次传入同一个p_id对应的100个ROWID批量取出C表记录,单次调用返回100行,所以执行计划ID=6的预估行数显示为100,总返回行数为2*100=200,和ID=1的总预估行数完全吻合。
为什么不是预期的1
你认为单个ROWID对应1行,所以预估行数应该为1,是误判了ID=6的单次调用逻辑:优化器在这里不会逐条传入ROWID调用表访问操作,而是会批量传入同一关联键对应的所有ROWID一次性取出数据,所以单次调用的返回行数是单个p_id对应的100条C表记录,而非1条。
内容的提问来源于stack exchange,提问作者Alex Bartsmon
相关产品推荐
相关产品推荐

