千家信息网

关于db_file_multiblock_read_count的研究分析

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,这期内容当中小编将会给大家带来有关关于db_file_multiblock_read_count的研究分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。初始化参数d
千家信息网最后更新 2024年11月19日关于db_file_multiblock_read_count的研究分析

这期内容当中小编将会给大家带来有关关于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能力应该有如下关系:

Max(db_file_multiblock_read_count) = MaxOsIOsize/db_block_size

当然这个Max(db_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_table(id int,name varchar(40)) 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_table(id int,name char(1000))
2 storage(freelists 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 substr(rowid, 1, 15) blockID, count(0)
2 from data_table
3 group by substr(rowid, 1, 15);

BLOCKID COUNT(0)
------------------------------ ----------
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次物理读。

上述就是小编为大家分享的关于db_file_multiblock_read_count的研究分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

0