|
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减小,有可能就会使得优化器不走索引,这也需要注意。
|
一共有 0 条评论