查询优化器参数 db_file_multiblock_read_count

 db_file_multiblock_read_count

数据库引擎在多块读取期间(例如,全表扫描或索引快速全扫描)使用的最大磁盘I/O大小是由db_block_size和db_file_multiblock_read_count初始化参数值的乘积决定的。因此,在多块读取期间读取的最大块数量是由最大磁盘I/O大小除以读取的表空间的块大小来决定的。换句话说,对于默认块大小,db_file_multiblock_read_count初始化参数指定的是读取的最大块数量。这里仅指最大的数量是因为,至少有以下三种常见情况会导致多块读取的数量要小于该初始化参数指定的值。

Ø  对于段头块和其他只包含像扩展映射这样的段元数据的块,都是通过单块读取的。

Ø  物理读从来不会横跨多个扩展,但有一个例外,就是针对使用自动段空间管理的表空间执行直接路径读。

Ø  已经在缓冲区中的数据块,除非是直接路径读,否则不会从磁盘I/O子系统重新读取。

举例说明,图9-2展示了在使用手工段空间管理的表空间中存储的段的结构。与其他任何段一样,它由扩展组成(在本例中有2个),每一个扩展都是由块组成的(在本例中有16个)。第一个扩展的第一个块是段头。某些块(4、9、10、19和21)已经缓存在缓冲区中。为这个段执行缓冲读的数据库引擎进程无法执行任何的物理多块读,即使db_file_multiblock_read_count初始化参数设置为大于或等于32的值也不行。



如果将db_file_multiblock_read_count初始化参数设置为8,则会执行下面这些缓冲读。

Ø  一次段头的单块读(块1)。

Ø  一次两个块的多块读(块2和块3)。因为块4已经缓存所以无法读取更多的块。

Ø  一次四个块的多块读(从块5到块8)。因为块9已经缓存所以无法读取更多的块。

Ø  一次六个块的多块读(从块11到块16)。因为块16是该扩展的最后一个块,所以无法读取更多的块。

Ø  一次两个块的多块读(块17和块18)。因为块19已经缓存所以无法读取更多的块。

Ø  一次块20的单块读。因为块21已经缓存所以无法读取更多的块。

Ø  一次八个块的多块读(从块22到块29)。因为db_file_multiblock_read_count初始化参数被设置为8,所以无法读取更多的块。

Ø  一次三个块的多块读(从块30到块32)。

概括起来,这个进程执行了两次单块读操作和6次多块读操作。一次多块读读取的平均块数量大概是4个。平均大小小于8的事实解释了为何Oracle会在系统统计信息中引入mbrc值。

db_file_multiblock_read_count初始化参数是动态的,并且可以在实例和会话级别修改。在12.1多租户环境下,也可以在PDB级别设置它。

这时候,讨论一下查询优化器是如何计算多块读操作(例如,全表扫描或索引快速全扫描)的成本也非常重要。

当有负载系统统计信息可用时, I/O成本并不依赖于db_file_multiblock_read_count 初始化参数的值。它是由公式9-1计算而来。注意,之所以用mreadtim除以sreadtim是因为查询优化器根据单块读正 常化了成本,就像在第7章中讨论的那样(公式7-2)。