CBO学习---第2章--表扫描(Tablescans)(四)
*+ cpu_costing */的计划到plan_table中,但最后的查询并没有查到它们,因为statement_id like '%N%'
[sql]
SQL> sta calc_mbrc
已选择 1 行。
会话已更改。
会话已更改。
表已删除。
表已创建。
表已分析。
PL/SQL 过程已成功完成。
已删除768行。
提交完成。
PL/SQL 过程已成功完成。
Id ACT_COST OLD_COST EFF_MBRC
---- ---------- ---------- ----------
1 76353 128000 1.676
2 48383 64000 2.646
3 37051 42667 3.455
4 30660 32000 4.175
5 26472 25600 4.835
6 23479 21333 5.452
... ... ... ...
125 3183 1024 40.226
126 3166 1016 40.442
127 3150 1008 40.648
128 3134 1000 40.855
已选择128行。
adjusted_mbrc值变化不大,比较准确,Oracle启动时,会根据所在的操作系统,来设置最大db_file_multiblock_read_count,并通过它来确定adjusted_mbrc
/**************************************************************************************************************************************/
本章代码附件中:
[sql]
tablescan_01.sql
中的最后一个查询,如下:
[sql]
alter session set db_file_multiblock_read_count = 8;
select
val, count(*)
from t1
group by
val
;
执行计划
----------------------------------------------------------
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)
表明两点:
(1)HASH GROUP BY并非像上面的SORT AGGREGATE不产生代价,而是产生了14的Cost,是否合理有待研究(8i中Cost为22)
(2)Rows为582显然是从系统表(user_tab_columns.num_distinct)中读取的,作为一个预估值放在这里。
/**************************************************************************************************************************************/
2.2Onwards & Upwards
转战Oracle9i,分析下9i的ASSM特性(负面影响太多,为特殊需求而定,平常不实用)。
2.2.1块大小的影响
在9i中,做8i中的同样查询,代价会明显增加1,这是由隐藏参数,"_tablescan_cost_plus_one=ture"引起的
这意味着,在做表扫描时,会先访问段头,获取段的本地管理信息(bitmap)等,以避免在非常小的表中,访问索引。
ASSM:不同的表空间使用不同的block_size的块;对此下面的代码,测试不同块大小下,如何根据db_file_multiblock_read_count值来计算cost
本章代码附件中:
[sql]
tablescan_01a.sql
tablescan_01b.sql
分别在block size不同的表空间中,建立测试表,然后进行mbrc的计算
发现随着block大小的变化,db_file_multiblock_read_count值也会发生变化,
block_size*db_file_multiblock_read_count(block_size下)的结果=8k*db_file_multiblock_read_count(8k下)
说明:一次从硬盘上读取的最大值=8k*db_file_multiblock_read_count(8k下),是一次性确定的,不会因ASSM改变而改变。
by the way
db_file_multiblock_read_count=128,是指128个操作系统块(0.5k)的说法,也听说过,有待研究
/**************************************************************************************************************************************/
2.2.2CPU代价计算
系统统计(system statistics)
是对于操作系统的一组参数,用于计算Cost。
[sql]
execute dbms_stats.gather_system_stats('start');
--隔一段时间
execute dbms_stats.gather_system_stats('stop');
'