本文档讨论DB_FILE_MULTIBLOCK_READ_COUNT参数的建议用法和设定。
1、何为DB_FILE_MULTIBLOCK_READ_COUNT?
初始化参数DB_FILE_MULTIBLOCK_READ_COUNT决定了,在一次全表扫描时,一次I/O操作所读取的数据库最大的块数。这个参数的设置可以减少一次全表扫描请求的I/O次数,从而提高数据库性能。
虽然将此参数设置为一个很高的值,可能全面提升数据库性能,是一个很诱人的想法,但是必须要考虑几个因素之后再进行设置。下面进行介绍。
2、这个参数是怎么工作的呢?
I/O是操作系统的一个函数,因为操作系统对此参数的设置划定了具体的限制。Oracle能够读取块大小是受操作系统一次I/O操作能够读到最多字节数限制的,(I/O参数 max_io_size),如果参数设置的值超过了操作系统最大限制值,参数值将被默认为O / S的默认值:(max_IO_size / db_block_size),因此设置此参数前应该先了解操作系统的I/O读取的参数max_io_size和限制值。
参数的设定决定了一个表完整扫描所需要请求的I/O次数,例如:如果参数DB_FILE_MULTIBLOCK_READ_COUNT=32,Oracle 块大小 DB_BLOCK_Size=8k,那么读取一个256K的表只需一次I/O操作,因此他提高了表扫描速度和查询性能。
3、调谐分析
事实上I/O总数都是被要求的 ,全表扫描取决于一些因素,例如:表大小,并行查询是否被使用等。基于成本的优化包括所有这些因素,包括参数DB_FILE_MULTIBLOCK_READ_COUNT设定的扫描表耗费的成本,基于成本的优化将使全表扫描比索引扫描耗费的成本更低。
下面给出全表扫描时的执行计划展现,通过BSTAT/ESTAT 统计报告展现出多块读取类似于读取散列的数据文件,散列读是指将不同的数据块通过缓冲池读取到数据块中,读取散列文件通常是全表扫描的耗费成本。BSTAT/ESTAT 是一个调谐init.ora 非常有用的工具。
设置DB_FILE_MULTIBLOCK_READ_COUNT参数的目的是使表扫描更快,I/O一次读取内容更多。这个值是通过每一个表扫描时所读取的块数,求得平均值得到的,目的是使每次的全表扫描只通过一次的I/O操作就可以完成。数据库调谐是一个反复迭代的过程,这是一个使用工具TKPROF分析应用程序细节和使用BSTAT/ESTAT统计分析或是使用动态视图例如v$sysstat and v$sesstat的过程。
4、限制性
设置DB_FILE_MULTIBLOCK_READ_COUNT参数需要考虑的几点重要问题。
了解你的应用对于你设置DB_FILE_MULTIBLOCK_READ_COUNT最佳参数是非常重要的,例如:OLTP应用很少执行。为全表扫描设置DB_FILE_MULTIBLOCK_READ_COUNT的参数很大是没有好处的,事实上可能会降低数据库性能,当要减少由于读取多块时所花费的相对成本,有些时候基于成本的优化对全表扫描更加有利。
如果DB_FILE_MULTIBLOCK_READ_COUNT设置过低,额外的I/O也被要求完成,有一个不足5个Oracle 块大小的数据组成的表和一个由5个或者更多的块组的大表,就需要对数据库的表和性能进行深入的分析了,DB_FILE_MULTIBLOCK_READ_COUNT受到操作系统的限制,修改参数值前应该查询Oracle对操作系统的系统要求的说明文档。
设置DB_FILE_MULTIBLOCK_READ_COUNT过高会使服务大量消耗系统内存并且导致全表扫描更频繁的选择基于成本的优化方式。
参数最优设置的计算方法:db_block_size * db_file_multiblock_read_count
DB_FILE_MULTIBLOCK_READ_COUNT受操作系统读取多块因素影响。
DB_FILE_MULTIBLOCK_READ_COUNT不能够超过操作系统I/O参数MAX_IO_SIZE 公式为:db_block_buffers/4。
综合衡量,设置值超过32将使获得的性能劣于32时的性能。
案例:
环境:On HP/UX RDBMS version 7.3.3.0, if the product 按公式计算参数 :(db_block_size * db_file_multiblock_read_count) 超过64K,会出现内核越界和Oracle错误ORA-7445 ,解决方法,减小db_file_multiblock_read_count 设置值,关重启实例。此Bug已经在版本7.3.3.3中解决 补丁包Patch 433762on version 7.3.2 for Solaris 可设置 db_file_multiblock_read_count = 128 Oracle为 8k db_block_size的块大小。