日历

2008 7.6 Sun
  12345
6789101112
13141516171819
20212223242526
2728293031  
«» 2008 - 7 «»

文章搜索

日志文章

2008年05月05日 15:38:23

db_file_multiblock_read_count对成本的影响

db_file_multiblock_read_count是一个非常重要的参数。
以下是reference对它的解释:
参数类型: Integer
默认值: 这个值对应最大的I/O大小,但是它是平台依赖的。
修改方法:ALTER SESSION, ALTER SYSTEM
值范围:依赖于操作系统
这个参数的意思是,在Table scan中,一次连续读(sequential read)能获取的最大块数。
当然这个值,不能超过操作系统和硬件的I/O极限。如果超过了,Oracle则会使用实际最大值。
一般在OLTP系统中,这个值是4~16,在我的测试环境中(PC server,8 disks RAID5),为16:
db_file_multiblock_read_count     integer   16
创建一个测试表:
SQL> select * from worksheet where rownum < 5001;
5000 rows selected.
SQL> SQL> SQL> exec show_space('TEST_WORK','APS2');
Unformatted Blocks .....................           0
FS1 Blocks (0-25) .....................           0
FS2 Blocks (25-50) .....................           0
FS3 Blocks (50-75) .....................           0
FS4 Blocks (75-100).....................           0
Full Blocks     .....................       2,128
Total Blocks............................       2,176
Total Bytes.............................     17,825,792
Total MBytes............................         17
Unused Blocks...........................           6
Unused Bytes............................       49,152
Last Used Ext FileId....................           2
Last Used Ext BlockId...................     3,067,017
Last Used Block.........................         122
PL/SQL procedure successfully completed.
这个表有2,128个数据块,平均每块不到三行。
现在,我来改变这个参数的大小,观察执行计划的变化。
alter session set db_file_multiblock_read_count = 4;
SQL> select * from test_work;
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   817   (1)| 00:00:10 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   817   (1)| 00:00:10 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 8
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   590   (1)| 00:00:08 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   590   (1)| 00:00:08 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 16
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   477   (1)| 00:00:06 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   477   (1)| 00:00:06 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 32
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   421   (1)| 00:00:06 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   421   (1)| 00:00:06 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 64
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   393   (1)| 00:00:05 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   393   (1)| 00:00:05 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 128
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   378   (1)| 00:00:05 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   378   (1)| 00:00:05 |
-------------------------------------------------------------------------------
alter session set db_file_multiblock_read_count = 256
-------------------------------------------------------------------------------
| Id | Operation       | Name     | Rows | Bytes | Cost (%CPU)| Time   |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       | 4822 |   10M|   378   (1)| 00:00:05 |
|   1 | TABLE ACCESS FULL| TEST_WORK | 4822 |   10M|   378   (1)| 00:00:05 |
-------------------------------------------------------------------------------
可以看出Cost呈现递减趋势 817   590   477   421   393   378   378   ,但是并不是和
参数值的成倍增加对应,而且设置为256的时候,实际已经达到极限。
关于COST的计算公式,书上说是:HW以下的数据块/db_file_multiblock_read_count
2,128/817   = 2.6046 ,参数是4
这里可能会有一点迷惑,因为除出来的结果不对应。那是因为db_file_multiblock_read_count
是指的最大I/O,而不是指的Oracle每次都会使用这个最大数,例如设置而4的时候,实际db_file_multiblock_read_count
的值在2~3之间,具体的算法不得而知。
通过这个测试可以看出,在当前环境下,较大的db_file_multiblock_read_count 可以获得较好
的Cost。但是我并不是说在所有环境都是这样,同样Cost也不完全和performance划等号。
在这个简单的单表连续读的扫描中,Cost基本就等于I/O成本,所有更大的值,可以提供较好的连续读性能。
在tuning guide曾经提及db_file_multiblock_read_count和等待事件'db file scattered read'有关系。
在tuning的过程需要具体分析。
同样它对优化器的选择也有影响,大值导致COST减小,有可能就会使得优化器不走索引,这也需要注意。



Tags: multiblock   oracle  

类别: Tuning |  评论(0) |  浏览(1966) |  收藏
发表评论