oracle包含的2种代价模型:
oracle通过隐含参数“_optimizer_cost_model"控制使用哪种代价模型
1io代价模型
cost=iocost
2cpu代价模型
cost=iocost+cpucost
在代价转换的过程中,所有的代价都转换为单数据块读的单次代价
存在四种类型的io,单块读,多块读,直接数据块读和直接数据块写
iocost=上述四种io的消耗
选择率与密度,空值,唯一值,以及柱状图数据有关。过滤条件的选择率
a and b a的选择率*b的选择率
a or b a的选择率+b的选择率-a*b
not a 1-a的选择率
在未引入系统统计信息之前,oracle会假设下面的2中情况是成立的:
1 单块读的平均消耗时间和多块读的平均消耗时间相等
2全表扫的时候,根据下面的情况计算全表扫描的成本
mbdivisor=1.675*power(db_file_multiblock_read_count,0.6581)
tsc=blocks/mbdivisor
10.2中的mbdivisor大约是4.4,11.2中的改值大约是3.6
cpu cost model在开启的情况下,全表扫描的计算公式如下:
tsc cost=i/o cost+cpu cost
i/o cost =1+ceil(blocks/mbrc)*(mreadtim/sreadtim)
cpu cost=round(#cpucycles/cpuspeed/1000/sreadtim)
系统的统计信息放在了aux_stats$中
查看统计信息收集的历史
wri$_optstat_tab_history
执行计划中的记录数是数据记录数*选择率,运行时间的估算,总的单数据块读的io代价*单次数据块读时间
全表扫描的大概估计:
索引范围扫描:分支节点读取的数据块数和叶子节点数据块数决定。分支节点数据块的读取数等于索引数的分支节点层数。叶子节点的计算是叶子节点数*条件选择率
所以索引的代价大概是层数+叶结点数*选择率*optimizer_index_cost_adj
索引rowid访问表的计算:这边涉及到一个聚簇因子,它是代表了数据块的聚集性。
iocost=索引树高度+叶子数据块数量*access的选择率+聚簇因子*filter的选择率*optica/100
索引范围扫描的计算公式:
i/o cost= index access i/o cost + table access i/o cost
index access i/o cost= blevel+ceil(#leaf_block*ix_sel)
table acess i/o cost=ce