CBO学习---第2章--表扫描(Tablescans)(七)

2014-11-24 16:41:46 · 作者: · 浏览: 4
611 2,717 1,936
64 388 2,717 1,806
128 246 2,717 1,740
将脚本中"-- tablespace test_8k"该行注释,一般默认表空间即为8k块的表空间,有此句反而可能过不去。
使用IO,得到第二列值
[sql]
alter session set "_optimizer_cost_model"=io
使用choose,并使用noworkload,得到第四列值
[sql]
alter session set "_optimizer_cost_model"=choose
begin
dbms_stats.set_system_stats('CPUSPEEDNW',913.641725);
dbms_stats.set_system_stats('IOSEEKTIM',10);
dbms_stats.set_system_stats('IOTFRSPEED',4096);
end;
/
使用choose,并使用workload,关闭清除系统统计,得到第三列值
[sql]
alter session set "_optimizer_cost_model"=choose
begin
dbms_stats.set_system_stats('MBRC',8);
dbms_stats.set_system_stats('MREADTIM',26.0);
dbms_stats.set_system_stats('SREADTIM',12.0);
dbms_stats.set_system_stats('CPUSPEED',913.641725);
end;
/
-- begin execute immediate 'begin dbms_stats.delete_system_stats; end;';
-- exception when others then null;
-- end;
/**************************************************************************************************************************************/
不管有没有系统统计,优化器只是用这些值来计算代价,执行器用db_file_multiblock_read_count来进行扫描,不是说mbrc=12,就每次扫描12个块。(有待研究)
当db_file_multiblock_read_count=8时,显然将MBRC设置为12是件很傻的事,但为了优化器的算法,相信我这么设置是对的,之后执行器每次会读取8个块。
/**************************************************************************************************************************************/
本章代码附件中:
[sql]
tablescan_04.sql
测试的是不同数据块下,noworkload在db_file_multiblock_read_count = 8时,所计算出的不同cost
[sql]
Block size noworkload normal
---------- ---------- ------
2K 7,729 10,854
4K 4,387 5,429
8K 2,717 2,717
16K 1,881 1,361
--没有实测,ASSM用的几率不高,懒得分析了
/**************************************************************************************************************************************/
2.2.2.1 CPU位
[sql]
Cost = (
#SRds +
#MRds * mreadtim / sreadtim +
#CPUCycles / (cpuspeed * sreadtim)
)
经上面IO位的计算
[sql]
Cost =5001 + #CPUCycles / (cpuspeed * sreadtim)
=5001 + #CPUCycles / (500 * 5000)
上面运行的结果中
[sql]
SELECT STATEMENT (all_rows) Cost(5031,1,4) New(5001,72914400,0)
SORT (aggregate)
TABLE ACCESS (analyzed) T1 (full) Cost(5031,10000,40000) New(5001,72914400,0)
New(5001,72914400,0),第二个参数为#CPUCycles
[sql]
Cost=5001 + 72914400 / (500 * 5000) =5001+29.2=5030.2
与结果5031相当接近
/**************************************************************************************************************************************/
2.2.3 CPU Costing的作用
本章代码附件中:
[sql]
cpu_costing.sql
执行完全相同的SQL语句,只是where条件的顺序不同
注意:使用/*+ cpu_costing ordered_predicates */ 这个hint来强迫Oracle遵循where后面条件的顺序来执行语句,否则Oracle的CBO将会自己选择最佳的次序。
[sql]
Id Par Pos Ins Plan
-- ---- ---- ---- -----------------------------------------------------------------------------------------------------------------------------------------------
0 6 SELECT STA