这期内容当中小编将会给大家带来有关关于db_file_multiblock_read_count的研究分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
初始化参数db_file_multiblock_read_count 影响Oracle在执行全表扫描时一次读取的block的数量。
db_file_multiblock_read_count的设置要受OS最大IO能力影响,也就是说,如果你系统的硬件IO能力有限,即使设置再大的db_file_multiblock_read_count也是没有用的。
理论上,最大db_file_multiblock_read_count和系统IO能力应该有如下关系:
Maxdb_file_multiblock_read_count) = MaxOsIOsize/db_block_size
当然这个Maxdb_file_multiblock_read_count)还要受Oracle的限制,目前Oracle所支持的最大db_file_multiblock_read_count 值为128。
data block是oracle最基本的读写单位,但用户所需要的数据,并不是整个块,而是块中的行或列。当用户发出SQL语句时,此语句被解析执行完毕,就开始了数据的抓取阶段,在此阶段,服务器进程会先将行所在的数据块从数据文件中读入buffer cache,这个过程叫做物理读。每读取一个块,就算一次物理读。
以我的理解,server process可能会尽可能一次多读一些相关行所属的block到buffer cache中,那么每读一个块都算做一个物理读吗?还是说每读一次(读的block数量和参数db_file_multiblock_read_count有关)就算一个物理读。
实际上,在使用db_file_multiblock_read_count的时候,一次如果读16个块,在oracle中仍按照16次物理读计算,并不按一次物理读计算。在操作系统级应该按一次I/O请求来计算。
下面,我们通过一个试验来验证以上情况。
SQL> show parameter db_file_multiblock_read_count
NAME TYPE VALUE
———————————— ———– ——————————
db_file_multiblock_read_count integer 16
这个值实际上是一次全表扫描的时要读取的数据块。
SQL> select file_name from dba_data_files;
FILE_NAME
——————————————————————————–
/oracle/database/orcl/users01.dbf
/oracle/database/orcl/sysaux01.dbf
/oracle/database/orcl/undotbs01.dbf
/oracle/database/orcl/system01.dbf
/oracle/database/orcl/DAT_DB
/oracle/database/orcl/xb_db
6 rows selected
SQL> create tablespace test
2 datafile '/oracle/database/orcl/testdb.dbf' size 10M
3 extent management local uniform. size 64K
4 segment space management manual;
Tablespace created
SQL> create table first_tableid int,name varchar40)) tablespace test;
Table created
为了测试需要,创建了一个新的表空间,并新增了一个数据表,查看表空间中该table的block分配情况如下:
SQL> select extent_id, block_id, blocks
2 from dba_extents
3 where wner = 'MS'
4 and segment_name = upper'first_table');
EXTENT_ID BLOCK_ID BLOCKS
———- ———- ———-
0 9 8
由于这个数据段是test表空间的第一个初始段,可以看到extent 0的第一个block是从9#开始,1-2#用于数据文件头,3-8#就是位图管理的信息,这里就不多介绍了。
为了进一步测试物理读的问题,通过举例数据表的读取来验证一下。
SQL> create table data_tableid int,name char1000))
2 storagefreelists 1 freelist groups 1)
3 pctfree 50
4 pctused 50
5 tablespace test;
Table created
SQL> show parameter db_block_size;
NAME TYPE VALUE
———————————— ———– ——————————
db_block_size integer 8192
根据创建数据段时设置的pctfree 50可以推算,一个block中可以存储大约三行的数据。
下面,插入测试数据。
SQL> begin
2 for i in 1 .. 47 loop
3 insert into data_table values i, 'just test data block allocate');
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed
SQL> commit;
Commit complete
SQL>
SQL> select substrrowid, 1, 15) blockID, count0)
2 from data_table
3 group by substrrowid, 1, 15);
BLOCKID COUNT0)
—————————— ———-
AAAuRMAAHAAAAAV 3
AAAuRMAAHAAAAAZ 3
AAAuRMAAHAAAAAX 3
AAAuRMAAHAAAAAh 2
AAAuRMAAHAAAAAS 3
AAAuRMAAHAAAAAd 3
AAAuRMAAHAAAAAb 3
AAAuRMAAHAAAAAW 3
AAAuRMAAHAAAAAf 3
AAAuRMAAHAAAAAc 3
AAAuRMAAHAAAAAT 3
AAAuRMAAHAAAAAU 3
AAAuRMAAHAAAAAY 3
AAAuRMAAHAAAAAa 3
AAAuRMAAHAAAAAe 3
AAAuRMAAHAAAAAg 3
16 rows selected
SQL> analyze table data_table compute statistics;
Table analyzed
SQL>
SQL> select num_rows, blocks, empty_blocks, num_freelist_blocks
2 from dba_tables
3 where wner = 'MS'
4 and table_name = upper'data_table');
NUM_ROWS BLOCKS EMPTY_BLOCKS NUM_FREELIST_BLOCKS
———- ———- ———— ——————-
47 20 3 5
可以看到数据段在HWM下共占有21个数据块,这里显示20是因为有一个块是段头,20个block中有5个block在freelist上面。
SQL> select file_id, extent_id, block_id, blocks
2 from dba_extents
3 where wner = 'MS'
4 and segment_name = upper'data_table');
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
———- ———- ———- ———-
7 0 17 8
7 1 25 8
7 2 33 8
SQL> alter session set events 'immediate trace name flush_cache';
Session altered
SQL> alter session set events '10046 trace name context forever,level 14' ;
Session altered
SQL> select id, name from data_table;
。。。
47 rows selected
SQL> alter session set events '10046 trace name context off';
Session altered
通过session级别的trace event 10046,得到SQL执行一次产生了21次物理读。