§1.1 简介
本文简要介绍了CBO成本计算的基本原理,并初步解释了初始化参数optimizer_index_cost_adj和db_file_multiblock_read_count对CBO的影响。
数据库版本为Oracle 9.0.1
平台为Windows2000
system@FXSB01> select *from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.0.1.1.1 - Production
PL/SQL Release 9.0.1.1.1 - Production
CORE 9.0.1.1.1 Production
TNS for 32-bit Windows: Version 9.0.1.1.0 - Production
NLSRTL Version 9.0.1.1.1 – Production
§1.4 初始化参数对执行计划的影响初探
n 初始化参数db_file_multiblock_read_count
下面是db_file_multiblock_read_count值与cost的换算因子
db_file_multiblock_read_count值 调整因子
4 4.175
8 6.589
16 10.398
32 16.409
64 25.895
128 40.865
test@FXSB01> show parameter db_file_multiblock_read_count
NAME TYPE VALUE
------------------------------------ ----------- -------------
db_file_multiblock_read_count integer 8
-- 根据表的统计信息和换算因子可以算出全表扫描的cost
test1 : 158/6.589=23.979约为24
test2 : 158/6.589=23.979约为24
test3 : 20/6.589=3.035约为4
均大于使用索引的cost
-- 修改该参数
test@FXSB01>
test@FXSB01> alter session set db_file_multiblock_read_count = 16
2 /
会话已更改。
test@FXSB01> select *
2 from test2
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=16 Card=20 Bytes=206
0)
1 0 TABLE ACCESS (FULL) OF 'TEST2' (Cost=16 Card=20 Bytes=2060
)
执行计划变成全表扫描,cost计算:使用索引的cost为21,使用全表扫描的cost=158/10.398=15.195,取整后为16.
test@FXSB01> select *
2 from test3
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=20 Bytes=60)
1 0 INDEX (RANGE SCAN) OF 'IDX_TEST3_N1' (NON-UNIQUE) (Cost=1
Card=20 Bytes=60)
执行计划保持不变,因为使用索引的cost为1,全表扫描的cost为20/10.398=1.923,取整为2
test@FXSB01>
test@FXSB01> alter session set db_file_multiblock_read_count=32
2 /
会话已更改。
test@FXSB01> select *
2 from test2
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=10 Card=20 Bytes=206
0)
1 0 TABLE ACCESS (FULL) OF 'TEST2' (Cost=10 Card=20 Bytes=2060
)
执行计划为全表扫描,cost计算:使用索引的cost为21,使用全表扫描的cost=158/16.409=9.628,取整后为10.选择全表扫描.
test@FXSB01> select *
2 from test3
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=20 Bytes=60)
1 0 INDEX (RANGE SCAN) OF 'IDX_TEST3_N1' (NON-UNIQUE) (Cost=1
Card=20 Bytes=60)
执行计划保持不变,因为使用索引的cost为1,索引叶块的一次物理读取.
n 初始化参数optimizer_index_cost_adj对执行计划的影响
n 参数optimizer_index_cost_adj是1到10000之间的一个百分值,表示索引访问和全表扫描之间相关物理I/O请求cost的一个比值.默认值100意味着索引访问与全表扫描是完全等价的.
n 最后cost=最初cost*optimizer_index_cost_adj/100
test@FXSB01> show parameter db_file_multiblock_read_count
NAME TYPE VALUE
------------------------------------ ----------- --------
db_file_multiblock_read_count integer 32
test@FXSB01> alter session set optimizer_index_cost_adj=50
2 /
会话已更改。
test@FXSB01> select *
2 from test2
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=10 Card=20 Bytes=206
0)
1 0 TABLE ACCESS (FULL) OF 'TEST2' (Cost=10 Card=20 Bytes=2060
)
执行计划为全表扫描,cost计算:使用索引的cost=1+20*0.5=11,使用全表扫描的cost=158/16.409=9.628,取整后为10.选择全表扫描.
test@FXSB01>
test@FXSB01> alter session set optimizer_index_cost_adj=25
2 /
会话已更改。
test@FXSB01> select *
2 from test2
3 where n1 = 100
4 /
已选择20行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=6 Card=20 Bytes=2060
)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST2' (Cost=6 Card=20 B
ytes=2060)
2 1 INDEX (RANGE SCAN) OF 'IDX_TEST2_N1' (NON-UNIQUE) (Cost=
1 Card=20)
执行计划选择了使用索引,cost计算:使用索引的cost=1+20*0.25=6,索引叶物理读取cost为1,表数据块物理读取为5;使用全表扫描的cost=158/16.409=9.628, 取整后为10,数据块物理读取cost为10,.选择使用索引.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7194105/viewspace-675326/ ,如需转载,请注明出处,否则将追究法律责任。