当前位置:文档之家› oracle+rac环境下索引热块的处理思路

oracle+rac环境下索引热块的处理思路

O O r r a a c c l l e e r r a a c c 环环境境下下索索引引热热块块争争用用的的处处理理思思路路修改记录目录1 Oracle rac环境下的索引热块争用 (4)1.1 场景总结 (4)1.2 处理思路 (4)2 关于索引使用的一些参考经验 (7)2.1 无法使用索引的场景 (7)2.2 如何创建合适的索引 (9)1Oracle rac环境下的索引热块争用1.1 场景总结1、多实例并发insert表导致的索引热块争用Oracle rac环境下多个节点同时对同一张表进行高频率的insert操作,由于需要对索引进行实时的维护,因此很容易引起索引的热块争用。

特别是当B*Tree索引中有一列是由递增的序列号产生的话(特别是主键字段),那么这些索引信息基本上分布在同一个索引叶块,当进行连续的insert操作时,索引块很容易产生争用。

解决的办法可以考虑采用反向索引或者按实例分区表的方式来处理。

2、多实例并发查询导致的索引热块争用主要分为以下两种情况:1)多实例并发查询的SQL语句的执行计划存在问题,采用了错误的执行计划或者是使用了不正确的索引,导致索引块的过度read,从而产生索引的热块争用。

这种情况通过对相关SQL语句的执行计划进行优化可以缓解索引的热块争用。

2)多实例并发查询的SQL语句的执行计划是正确的,但是由于select的频率非常高,容易造成双机之间索引块的gc等待。

对于这种情况建议应用分实例分模块连接查询,避免多实例同时对同一张表(索引)进行并发查询。

1.2 处理思路1、反向索引反向索引是B*Tree索引的一个分支,它的设计是为了运用在某些特定的环境下的。

Oracle推出它的主要目的就是为了降低在rac环境下索引叶块的争用。

当B*Tree索引中有一列是由递增的序列号产生的话(特别是主键字段),那么这些索引信息基本上分布在同一个索引叶块,当用户修改或访问相似的列时,索引块很容易产生争用。

反向索引中的索引码将会被分散到各个索引块中,从而减少了索引争用。

注:使用REVERSE类型的索引在查询操作时会被限制使用基于索引区间的扫描(index range scans)。

范例:问题描述:应用系统需要短时间内对表集中插入数据,通过观察发现该表的一些特征;1)主键是使用SEQUENCE单调递增生成的。

2)对该表的查询不会对主键字段进行范围查询(index range scan)。

优化思路:最为直接的办法就是去掉索引、主键。

如果该主键不能停止或直接删除,那么在这种情况下,可以考虑将该主键改造成为REVERSE类型的主键。

这种通过序列、时间戳或按某种规则单调生成主键的表,可以因为使用REVERSE(反转)类型索引来有效的降低索引“单向右增长”(right-growing index)的可能性。

具体脚本:Create index ******************* reverse;或者alter index ****** rebuild online reverse;2、按实例分区表在rac环境下,为了获得良好的双机性能,关键在于应用程序架构需要按实例分模块,不同的模块连接不同的数据库实例。

如果前期应用设计不理想,那么rac数据库就有可能出现严重的global cache争用。

因此根本解决rac的global cache的途径还是应用架构的模块化设计。

另外通过对表按实例进行分区也有助于缓解表和索引的rac争用。

范例:问题描述:crm数据库的o_oss_log表,两个实例对该表存在大量的insert操作,由于应用模块没有分实例或者单实例插入,数据库出现了严重的表和索引的gc cr request等待。

优化思路:对o_oss_log表进行如下改造:1)增加inst_id字段2)对表增加2级分区,SUBPARTITION BY LIST ("INST_ID"),对表执行插入操作时,首先获取当前连接的instance_id,然后实现分实例insert操作。

具体脚本:1)获取当前的instance_idSelect sys_context(‘USERENV’,’INSTANCE’) FROM DUAL;2)按实例分区表建表脚本:CREATE TABLE "CRM"."O_OSS_LOG"( "LOG_ID" V ARCHAR2(15) NOT NULL ENABLE,"REQ_DATE" DA TE NOT NULL ENABLE,"REQ_SERVICE_NAME" V ARCHAR2(50),"RESULT" V ARCHAR2(100),"IN_XML_MSG" CLOB,"OUT_XML_MSG" CLOB NOT NULL ENABLE,"FINISH_DATE" DA TE NOT NULL ENABLE,"ORDERID" V ARCHAR2(30),"PRODID" V ARCHAR2(30),"INST_ID" NUMBER)TABLESPACE "TBS_OTHERS"PARTITION BY RANGE ("REQ_DATE")SUBPARTITION BY LIST ("INST_ID")SUBPARTITION TEMPLA TE(SUBPARTITION "INST1" values ( 1 )TABLESPACE "TBS_SO" ,SUBPARTITION "INST2" values ( 2 )TABLESPACE "TBS_SO"SUBPARTITION "OTHER" values ( DEFAULT )TABLESPACE "TBS_SO")(PARTITION "PART_01" V ALUES LESS THAN (TO_DATE(' 2009-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)TABLESPACE "TBS_SO",PARTITION "PART_02" V ALUES LESS THAN (TO_DA TE(' 2009-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)TABLESPACE "TBS_SO",PARTITION "PART_03" V ALUES LESS THAN (TO_DATE(' 2009-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)TABLESPACE "TBS_SO",PARTITION "PART_04" V ALUES LESS THAN (TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)TABLESPACE "TBS_SO",PARTITION "PART_05" V ALUES LESS THAN (TO_DATE(' 2010-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 MINEXTENTS 1 MAXEXTENTS 2147483645 BUFFER_POOL DEFAULT)TABLESPACE "TBS_SO")注:从实际使用效果来看,以上两种方式对insert操作引起的索引热块争用有一定效果,但对select操作由于无法做到分实例查询,效果不明显。

2关于索引使用的一些参考经验2.1 无法使用索引的场景在SQL中有很多陷阱会使一些索引无法使用。

下面讨论一些常见的问题:1、使用不等于操作符(<>、!=)下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。

select * from test where test_id <> 'gb';把上面的语句改成如下的查询语句,这样将会使用索引。

select * from test where test_id < 'gb' or test_id > 'gb';特别注意:通过把不等于操作符改成OR条件,就可以使用索引,以避免全表扫描。

相关主题