RAC环境下的索引优化

作者简介:石云华,现就职于北京海天起点,oracle技术二线专家成员,Exadata部门负责人。拥有十余年电信、保险、税务行业核心系统ORACLE数据库运维经验,持有11gOCM、Exadata、Goldengate等证书。擅长于oracle/goldengate/exadata方面的故障诊断及疑难问题处理。

通常在RAC中进行大批量的insert的时候,查看AWR中有这些事件的时候说明发生索引块的竞争:

Oracle10g中的等待事件名称:

gc buffer busy

gc current block busy

gc current split

enq: TX – index contention

在Oracle 10g中,从视图V$SEGMENT_STATISTICS可以区分出活跃块的究竟是’gc buffer busy’ (global)类型的还是’buffer busy waits’ (local)类型的。当然视图V$SEGMENT_STATISTICS不能区分undo buffer的信息。因此需要使用两个视图,V$CR_BLOCK_SERVER 和 V$WAITSTAT来确定到底是索引块的竞争还是undo块的竞争。

还可以用诊断事件event 10046 level 8可以显示详细的等待事件信息,它可以把所有的buffer busy 和 global cache 事件显示出来。

一旦我们确定有索引块竞争情况的发生之后,可以采用如下措施减少它的危害:

增加sequence字段的缓存

在sequence字段上建立的索引,当发生insert时,很容易出现索引块竞争的情况。如果有这种索引的时候,当必须大批量insert的时候,就需要减少节点之间的索引块的传输来提高性能。最简单的方式就是增加sequence字段的缓存。

比较理想的sequence字段的缓存大小应该是多少,这个值一定要考虑插入的数量级,插入越多缓存就要越大。在测试实践中,我们发现如果每秒插入2000条数据的情况下,缓存大于50000得到的性能最好。考虑到索引键值不同和并发的插入数目不同的情况,这个值仅供参考。

这种方法有如下的优势:

•    容易使用,不需要重建索引段

•    能够有效减少global cache和global buffer busy contention

缺点是:

•    只适用于Oracle sequences字段上的索引.

•    Sequence字段必须是CACHE NOORDER类型的.

建立反向索引

可以参考使用如下语句来建立反向索引:

反向索引能够减少buffer busy contention

这种方式的优点:

•    容易实现,只要把那些产生了索引块竞争的索引重建一下

•    能把INSERT插入的数据分布到多个索引块.

•    单节点环境采用反向索引也能有效减少buffer busy contention 和cache buffers chains latch。

缺点:

•    造成where语句只能使用 “where col = value” 而不能使用”where col > value” 。

•    不能减少索引块的节点之间的传输。

对表或者索引使用Hash分区

Hash 分区能减少buffer busy contention ,于使用反向索引类似。在Oracle 10g 支持对索引的进行分区,使用时注意以下几点:

分区的字段

首先确定表的哪个或者哪几个字段用来进行分区.有两点值得考虑:

字段能经常被查询使用为查询条件

字段的值具有唯一性,具有唯一性的字段才能有效的把不同值按hash算法分到不同分区中

分区的个数

从以下角度考虑分区的个数:

•    由于使用hash算法,分区的个数为2的倍数话,数据能有更好的分散性。

•    一般分64个分区之后,能够看到INSERT操作中的竞争情况明显减少。但是超过64个分区之后,这种减少的趋势就不怎么明显了。

•    当然分区的数目也由INSERT的频度和并行度有关。

•    分区数过多也会造成buffer cache内存占用过多。

选择不同的索引类型 – LOCAL 类型或者 GLOBAL类型

对分区表上的索引,需要选择不同的索引类型。

如果索引需要和表的分区保持一致,就应使用LOCAL类型的索引。不需要一致的时候,使用GLOBAL类型的索引能避免查询时扫描多个索引分区,但是有可能会产生buffer busy contention。

对表进行按照INSTANCE_NUMBER的list类型的分区

如何对表进行按照INSTANCE_NUMBER的list类型的分区?

•    在表上面加一个字段INSTANCE_NUMBER 这个字段将会保存当前创建表的实例的id。

•    对表进行按照INSTANCE_NUMBER的list类型的分区,分区结果就是按照RAC中的实例数目分成了不同分区

参考语句如下:

这样,并行的INSERT 操作就会对应不同的分区.如果在使用了LOCAL类型的索引,就能很大程度的减少current block的传输.

不使用global cache defers

如果使用了按照hash分区或者反向索引的时候,global cache defers会造成性能下降。

可以使用以下语句关闭:

未经允许不得转载:Oracle一体机用户组 » RAC环境下的索引优化

相关推荐