9i DB_FILE_MULTIBLOCK_READ_COUNT参数和extent大小的设置

Oracle通过两种方式从表中获取数据:

·          通过ROWID(通常使用索引扫描时)

·          通过全表扫描

如果通过ROWID读取数据,表中的区间数就不是读性能的一个因素(如果使用并行查询,那么一个表中有较多的区间的数量可以明显提高I/O的性能),Oracle将通过ROWID直接找到需要的行,并获取相应数据。

如果是全表扫描,那么区间的尺寸大小就有可能导致性能问题。因为全表扫描时,Oracle会一次读取多个Blocks。每次读取的块数将受初始化参数DB_FILE_MULTIBLOCK_READ_COUNT和操作系统的I/O缓冲区大小的限制。比如说,如果Oracle Block的大小是4KB,操作系统I/O缓冲区大小是64KB,那么在全表扫描时每次最多可以读取16各块(Oracle Blocks),所以此时将DB_FILE_MULTIBLOCK_READ_COUNT的值设置为超过16也改变不了全表扫描的性能了。

通常,设置DB_FILE_MULTIBLOCK_READ_COUNT参数是如下考虑的:

(1)         使用一个单独的数据文件创建一个新的表空间

(2)         在该表空间中创建一个单独的未索引的表

(3)         查询V$FILESTAT以验证该测试的初始统计值

(4)         在表上执行全表扫描

(5)         查询V$FILESTAT以确定该测试的终止统计值,并从中减去开始统计值。将PhyBlkRds值除以PhyRds以确定有效的多块读计数。

(6)         删除这个用于测试的表空间

C:\>sqlplus "/as sysdba"

 

SQL*Plus: Release 9.2.0.1.0 - Production on 星期六 6月 28 10:11:22 2003

 

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

 

已连接到空闲例程。

 

SQL> startup

ORACLE 例程已经启动。

 

Total System Global Area   93395628 bytes

Fixed Size                   453292 bytes

Variable Size              67108864 bytes

Database Buffers           25165824 bytes

Redo Buffers                 667648 bytes

数据库装载完毕。

数据库已经打开。

SQL> show parameter db_block_size;

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ---------------------

db_block_size                        integer     8192

SQL> show parameter DB_FILE_MULTIBLOCK_READ_COUNT;

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ----------

db_file_multiblock_read_count        integer     16

SQL>

 

使用一个单独的数据文件创建一个新的表空间:

SQL> create tablespace lunar

  2  datafile 'd:\lunar.dbf' size 10m

  3  default storage(initial 1m next 1m pctincrease 0);

 

表空间已创建。

 

在该表空间中创建一个单独的未索引的表:

SQL> create table lunar

  2  tablespace lunar

  3  as select * from dba_objects;

 

表已创建。

 

SQL> select relative_fno from dba_data_files

  2  where tablespace_name='LUNAR';

 

RELATIVE_FNO

------------

          15

 

查询V$FILESTAT以验证该测试的初始统计值:

SQL> select phyrds,phyblkrd from v$filestat

  2  where file#=15;

 

    PHYRDS   PHYBLKRD

---------- ----------

         0          0

 

在表上执行全表扫描:

SQL> select count(*) from lunar;

 

  COUNT(*)

----------

     27547

 

查询V$FILESTAT以确定该测试的终止统计值:

SQL> select phyrds,phyblkrd from v$filestat

  2   where file#=15;

 

    PHYRDS   PHYBLKRD

---------- ----------

        24        376

 

SQL>

 

PHYRDS 和 PHYBLKRD 的初始统计的值都是0;

PHYRDS 和 PHYBLKRD 的终止统计的值分别是24和 376;

PHYRDS 的终止统计的值 - PHYRDS 的初始统计的值 =24;

PHYBLKRD 的终止统计的值 - PHYBLKRD 的初始统计的值 =376;

PHYBLKRD 的差值 / PHYRDS 的差值 = 15.67

所以,有效的多块读计数是16

需要注意的是,如果不是用新的表空间测试,那么测试得到第3步和第5步的差值后,在会话级改变DB_FILE_MULTIBLOCK_READ_COUNT参数,然后再次得到第3步和第5步的差值,并重复测过程。

记住,不要将DB_FILE_MULTIBLOCK_READ_COUNT参数设置的比计算的值高。

  

设置区间尺寸大小的考虑思路应该是合理的利用Oracle的能力以便在全表扫描时执行多块存取,同时读操作又是不能跨区间的。举个例子,假设操作系统I/O缓冲区大小是64KB,考察读取一个640KB大小的表,如果设置为每个区间64KB,一共10个区间,如果执行全表扫描,则Oracle需要10次读操作(相当于一次读一个区间);如果设置为一个640KB的区间,则Oracle还是需要10次读操作(因为操作系统I/O缓冲区大小是64KB),可见压缩区间并不能提高性能;如果设置为每个区间80KB,一共8个区间,则每个区间Oracle需要读两次,第一次读64KB,第二次读这个区间剩余的16KB(读操作不能跨区间),所以总共需要16次读操作(相当于一次读一个区间)。区间尺寸的设置对性能的影响是显而易见的。

     综上,总结起来设置区间大小时需要考虑下面的问题:

·          创建明显大于或者等于操作系统I/O缓冲区大小的区间(最好是操作系统I/O缓冲区大小的整数倍)。这样,如果区间非常大,即使区间大小不是操作系统I/O缓冲区大小的整倍数,也只需要很少的附加读操作(如果上面的640KB和80KB的差异)。

·          设置DB_FILE_MULTIBLOCK_READ_COUNT以充分利用操作系统I/O缓冲区的大小。应考虑DB_FILE_MULTIBLOCK_READ_COUNT <= 操作系统I/O缓冲区 / Oracle Block的大小,如果DB_FILE_MULTIBLOCK_READ_COUNT设置的太大,会使优化器认为全表扫描更有效而改变执行计划,然后实际情况并非如此。

·          如果必须创建小的区间,创建其大小是操作系统I/O缓冲区大小的整数倍

posted @ 2013-06-13 15:08  cav5lier  阅读(270)  评论(0编辑  收藏  举报