对Oracle进行优化时,一个要点在于对RAM数据缓冲区进行有效的治理。假如能将数据块存储到作为数据缓冲区使用的RAM中,从而避免物理性的写盘操作,Oracle的性能就能获得显著增强。
以前,Oracle专家在分配RAM缓存区域时,需要定义db_block_buffers参数(在Oracle 9i中是db_cache_size)来指定这个缓存的大小。然后,让Oracle来治理这个RAM区域中的数据块。但在Oracle 9i中,由于增加了对多个块大小的支持,所以你能治理每个单独的数据缓冲池,并将表和索引隔离到几个独立的数据缓冲区中。
Oracle缓存入门
SQL语句从表中请求一个行时,Oracle首先检查内部内存结构,核实数据是否在一个数据缓冲区中。假如是,就从那里返回请求的数据,从而避免一次物理性的IO操作。在Oracle的某些64位版本中,由于SGA非常大,所以小型数据库可以整个儿缓存下来,这已经在“Tweak Oracle data buffer parameters to cache entire databases” 一文中进行了讨论。但是,对于非常大的数据库来说,RAM数据缓冲区无法容纳所有数据库块。
Oracle答应将频繁使用的块放到RAM中。假如数据缓冲区不足以容纳整个数据库,Oracle会通过“最不常用”(least-recently-used)算法,判定要将数据库的哪些页从内存刷新回数据库中。Oracle在数据缓冲区中为每个块都维持了一个驻留内存的控制结构:新数据块插入数据缓冲区的中部,一个块每次被请求时,都会移至列表开头。最少用的数据块会逐渐落到数据缓冲区的末尾,最终被删除,以便为新数据块腾出空间。
从Oracle 8开始,Oracle提供了3个独立的RAM池来容纳进入的Oracle数据块:
KEEP池用于容纳应用程序常用的表,比如一些要经常进行表扫描操作的小表。
RECYCLE池为一些大型表保留,它们要进行全表扫描,而且通常不会重读。使用RECYCLE池后,进入的数据块就不会将数据块从更常用的表和索引中刷新出去。
DEFAULT池用于容纳不适合放到KEEP或RECYCLE中的其他所有表和索引。
记住,KEEP和RECYCLE池只是DEFAULT池的子集。理解了Oracle数据缓冲区的基本机制后,接着来看看如何利用数据字典查询来查看缓冲区的内容。
针对数据缓冲区的字典查询
Oracle提供了v$bh视图,答应你查看数据缓冲区的内容,以及查看缓冲区中为每个segment类型使用的块的数量。假如使用了多个数据缓冲区,而且想知道为表和索引使用的缓存容量,这个视图就尤其有用。将v$bh视图与dba_objects结合,就能逐块列出数据缓冲区的内容,并了解数据缓冲区具体如何对表和索引内容进行缓存。
清单A 中的脚本将数据缓冲区的信息格式化为一个不错的报表,你可用它监视数据库中的数据缓冲区活动。图A展示了该报表的输出。
图A
数据缓冲区活动报表
如清单A所示,这个报表能提供非常有价值的信息,使数据缓冲区中的表和索引都能一目了然。假如你为数据缓冲区预备的RAM资源有限,这个报表可清楚地显示缓冲区中为每个对象使用的块数。
Oracle的中点插入(midpoint insertion)算法将每个缓冲区都分解成“热”和“冷”两个区域,具体则取决于每个数据块被读取的频率。一个数据块每次被重新引用时,都会移动到数据块链条的头部,从而进入数据缓冲区的“热”区。可反复运行这个报表,监视数据块在冷热两个区域移动的情况。