CBO学习---第2章--表扫描(Tablescans)(三)
--------------------
| 0 | SELECT STATEMENT | | 1 | 4 | 393 |
| 1 | SORT AGGREGATE | | 1 | 4 | |
| 2 | TABLE ACCESS FULL| T1 | 10000 | 40000 | 393 |
-----------------------------------------------------------
Note
-----
- cpu costing is off (consider enabling it)
会话已更改。
db_file_multiblock_read_count = 128
执行计划
----------------------------------------------------------
Plan hash value: 3724264953
-----------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4 | 250 |
| 1 | SORT AGGREGATE | | 1 | 4 | |
| 2 | TABLE ACCESS FULL| T1 | 10000 | 40000 | 250 |
-----------------------------------------------------------
Note
-----
- cpu costing is off (consider enabling it)
会话已更改。
执行计划
----------------------------------------------------------
Plan hash value: 136660032
-----------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------
| 0 | SELECT STATEMENT | | 582 | 2328 | 1555 |
| 1 | HASH GROUP BY | | 582 | 2328 | 1555 |
| 2 | TABLE ACCESS FULL| T1 | 10000 | 40000 | 1541 |
-----------------------------------------------------------
Note
-----
- cpu costing is off (consider enabling it)
在清除了系统统计和关闭CPU_Costing时,随着db_file_multiblock_read_count的增加,Cost逐步减小
上面的结果是该脚本在10g下运行的,虽然关闭了cpu_costing,但所计算的cost仍然比8i下略大
/**************************************************************************************************************************************/
传统COST的计算公式,从下面推算出来
[sql]
CPU costing model:
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
#CPUCycles / cpuspeed
) / sreadtim
本示例中,#SRds=0(刚建立的新表,没有经过删改,没有碎片,只是连续10000个块的读取,没有单块),#MRds=10000,CPU_Costing关闭了。
[sql]
Cost=#MRds * mreadtim/sreadtim
adjusted_mbrc=mreadtim/sreadtim;即典型多块读取,平均一次读多少块。(adjusted_mbrc为调整后的dbf_mbrc,只用来计算cost用)
注意:adjusted_mbrc的值,在未使用系统统计和关闭CPU_Costing时,只与db_file_multiblock_read_count有关;在使用系统统计后,就使用系统统计的值来计算cost。
[sql]
Cost=10000/adjusted_mbrc
根据上面脚本执行后,不同db_file_multiblock_read_count值下的Cost值(该值为书中的8i值),可计算出adjusted_mbrc,统计于下表中
[sql]
db_file_multiblock_read_count Cost Adjusted dbf_mbrc
4 2,396 4.17
8 1,518 6.59
16 962 10.40
32 610 16.39
64 387 25.84
128 245 40.82
db_file_multiblock_read_count与adjusted_mbrc为一一对应关系,例如:db_file_multiblock_read_count=32时,扫描23729个块的表时,代价为ceil(23729/16.39)
/**************************************************************************************************************************************/
本章代码附件中:
[sql]
calc_mbrc.sql
通过dbms_stats.set_table_stats,欺骗优化器,指出T1表有128000个块,平均行长3500,来让优化器算出更加准确的Cost,来计算adjusted_mbrc.
详细列出db_file_multiblock_read_count从1到128,/*+ nocpu_costing */下,所对应的mbrc值,OLD_COST值可能是比8i还早的Cost值
虽然输出了/