CBO学习---第2章--表扫描(Tablescans)(六)
(Cost=5032 Card=10000 Bytes=40000)
/**************************************************************************************************************************************/
[sql]
alter session set db_file_multiblock_read_count = 8;
[sql]
--将下面语句放入TARGET.SQL中
select
val, count(*)
from t1
group by
val
;
--运行plan_run92.sql
@plan_run92
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)
[sql]
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
#CPUCycles / cpuspeed
) / sreadtim
将sreadtim移到括号内
[sql]
Cost = (
#SRds +
#MRds * mreadtim / sreadtim +
#CPUCycles / (cpuspeed * sreadtim)
)
--#SRds=0
--#MRds=blocks/mbrc=10000/12
Cost=(10000/12*30/5)+CPUCycles / (500 * 5)=5000+ CPUCycles/2500
_tablescan_cost_plus_one
Cost=5001+ CPUCycles/2500
/**************************************************************************************************************************************/
2.2.2.1 IO位
[sql]
IOcost=#MRds * mreadtim / sreadtim
IOcost=10000/12*30/5 --其实mreadtim的单位为ms,计算中是需要10^-6s为单位,应该加3个0,只是对于sreadtim的比值说,结果是一致的。
_tablescan_cost_plus_one=ture
IOcost=5001;与下面new中的IOcost相同
[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)
在使用系统统计后,mbrc的实际值不再是根据db_file_multiblock_read_count所算出adjusted_mbrc值了
实际MBRC=system mbrc*mreadtim/sreadtim
/**************************************************************************************************************************************/
10g中,如果没有收集系统统计(或删除了系统统计),你会发现下面的三组值,用于无负载状态(noworkload)
[sql]
SQL> exec dbms_stats.delete_system_stats;
PL/SQL 过程已成功完成。
select
pname, pval1
from
sys.aux_stats$
where
sname = 'SYSSTATS_MAIN';
PNAME PVAL1
------------------------------ ----------
CPUSPEED
CPUSPEEDNW 2287.401
IOSEEKTIM 10
IOTFRSPEED 4096
MAXTHR
MBRC
MREADTIM
SLAVETHR
SREADTIM
已选择9行。
nowordload时,就会用这三个值去就计算cost
[sql]
MBRC =db_file_multiblock_read_count
sreadtim =IOSEEKTIM+db_block_size/IOTFRSPEED
mreadtim =IOSEEKTIM+db_block_size*db_file_multiblock_read_count/IOTFRSPEED
如果db_file_multiblock_read_count=8
MBRC=8
sreadtim=10+8192/4096=12ms
mreadtim=10+8192*8/4096=26ms
如果db_file_multiblock_read_count=16
MBRC=16
sreadtim=10+8192/4096=12ms
mreadtim=10+8192*16/4096=32ms
因此,使用nowordload计算cost时,cost会随db_file_multiblock_read_count变化而变化
本章代码附件中:
[sql]
tablescan_03.sql
设置noworkload的三个参数,清除其他workload参数,然后计算cost值,统计入下表中
[sql]
db_file_multiblock_read_count Traditional Standard cpu_costing Noworkload cpu_costing
4 2,397 2,717 3,758
8 1,519 2,717 2,717
16 963 2,717 2,196
32