优化参数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3. db_file_multiblock_read_count
在多块(multiblock)读的情况下(例如,在全表扫描或快速全索引扫描时),数据库引擎使用的最大I/O大小取决于初始化参数db_file_multiblock_read_count和db_block_size的乘积。因此在多块读时最大的块数是用最大的I/O吞吐量除以一个块的大小得到的。换言之,对默认的块尺寸来说,初始化参数db_file_multiblock_read_count的值指定了一次最多可读取的数据块数目。这“仅仅”是一个理想的最大值,因为通常至少有下列三种情况可能导致一次多块读的数目少于此初始化参数指定的值。
⊙读段头时单块读。
⊙物理读不能跨越多个区(extent)。
⊙部分数据块已经在高速缓存(buffer cache)中,除非是直接读,否则不会从I/O子系统重新读取。
为了阐述清楚,下图展示了数据库中一个段(segment)的结构。
跟其他段一样,它由若干个区(extent)组成(在本例中,是两个区),每个区由若干个块组成(在本例中,是16个块)。第一个区的第一个块为段头块(segment header)。其中一些块(第4、9、10、19和21块)被缓存在高速缓存中。一个数据库进程对这个段执行一次串行的全扫描(并行全扫描有其特殊的行为,将在后面介绍),并不能通过一次单独的物理读就完成。即使初始化参数db_file_multiblock_read_count的值被设置为32或者更大也不能。
如果初始化参数db_file_multiblock_read_count被设置为8,将会造成如下的物理读过程。
⊙一个单块(single-block)读获取段头(块1)。
⊙一个多块(multiblock)读得到两个块(块2和3)。不能一次读更多的块因为块4被缓存。
⊙一个多块读读取4个块(从块5到块8)。不能读更多的块因为块9被缓存。
⊙一个多块读读取6个块(从块11到块16)。不能读更多的块因为块16是一个区的最后一个块,不能跨区读。
⊙一个多块读读取2个块(块17和块18)。不能读更多的块因为块19被缓存。
⊙一个单块读块取块20。不能读更多的块因为块21被缓存。
⊙一个多块读读取8个块(从块22到块29)。不能读更多的块因为初始化参数db_file_multiblock_read_count被设置为8。
⊙一个多块读读取3个块(从块30到块32)。
总之,这个进程共进行了两个单块读和六个多块读。平均每个多块读的块数约为4。平均每次读块的数目小于参数设置值8的事实,解释了Oracle在计算系统统计信息时引入变量mbrc的原因。
在此,了解查询优化器如何计算多块读的开销也是很重要的(比如,在全表扫描或快速全索引扫描时)。就像Wolfgang Breitling 在他的文章“A Look Under the Hood of CBO: The 10053 Event”中指出的那样,当系统统计信息不可用时,这个开销可用下列公式来近似地计算。
无系统统计时多块读操作的I/O 开销
当工作量系统统计信息可用时,I/O的开销不再只取决于初始化参数db_file_multiblock_read_count的值。而是用下列公式计算。
注意到变量mreadtim被sreadtim除是因为查询优化器通常是根据单块读来换算开销的。这点已在以前讨论过。
在公式中,如果是用非工作量统计信息,mbrc的值就用初始化参数db_file_multiblock_read_count的值来代替。
这意味着初始化参数db_file_multiblock_read_count仅在工作量统计信息不可用时,对多块读操作的开销计算有直接的影响。这也暗示着此初始化参数太大可能导致过度的全扫描或者至少低估了多块读操作的开销。进一步讲,这是工作量统计信息好于非工作量统计信息或者根本没有系统统计信息的又一个例子。
既然已经了解开销计算公式,关键在于如何找到公式中变量的合适值。最重要的是认识到多块读是一种和性能相关的特性。因此需要设置初始化参数db_file_multiblock_read_count以求获取最佳性能。为了达到这个目的,必须认识到并不是所有情况下值越大性能就越好。此外,将值设置为超过操作系统所能支持的物理I/O上限也是毫无意义的,这个上限是max I/O chunk size。对一个简单的全表扫描分别设置不同的参数值测试性能,可以获得这个参数对性能产生影响的有效信息,有助于发现它的最佳值。下面的PL/SQL代码块,参看脚本assess_dbfmbrc.sql,可用于此目的。
如你所见,做到这一点并不难,因为初始化参数db_file_multiblock_read_count是动态的并且可以在实例级和会话级修改。无论如何,千万小心不要在数据库、操作系统和I/O子系统层级缓存测试表的数据,否则将导致测试结果无效。避免它最容易的方法就是使用一张比系统中可用的最大缓存还要大的表来做测试。有一点要注意的是不要使用并行处理,因为通常数据库引擎通过不同的系统调用来执行并行全表扫描和串行全表扫描。
通过上面PL/SQL块的测试,显示出下列几种不同系统特性。
◎测试环境1:
随着I/O尺寸的增加,性能不断提升,一直到每次8左右。更大的值收效不大,甚至出现负增长。所以该多块读不易设置大于8
◎测试环境2:
一直到每次16块性能增长都很缓慢(每次增幅不超过10%)。当从16调到18时,性能骤然上升20%左右。超过18以后又表现平平。对这种系统,参数设置要避免小于18。
◎测试环境3:在参数达到8之前性能提升都很显著,在8到16之间,增长基本平缓。当从16到17时,出现16%的负增长。因此对这种系统来说,此参数值需要避免达到16以上。
◎测试环境4:系统的性能与此I/O的尺寸无关。
从Oracle 10g R2起,也可以指示数据库引擎自动配置初始化参数db_file_multiblock_read_count的值。使用这个特性的方法很简单,就是不手动设置此参数的值。
在10GR2,理论上,最大db_file_multiblock_read_count和系统IO能力应该有如下关系: Max(db_file_multiblock_read_count) = max