大数量的DML时对索引处理的技巧

进行大数据量的DML时,数据处理会很慢,甚至数据处理直接卡死。对此优化的技巧之一就是先将表在DML中查询用不到的索引置为无效以及nologging,DML处理完后再将这索引重建。

1 新建存储要置为无效的索引的临时表

create global temporary table TMP_VACHAR_LIST
(
  text VARCHAR2(4000)
)
on commit preserve rows;

2 将索引置为无效,数据处理后重建索引

begin
  EXECUTE IMMEDIATE 'TRUNCATE TABLE TMP_VACHAR_LIST';
  --记录下来非唯一性约束,插入数据后要重建
  INSERT INTO TMP_VACHAR_LIST
    SELECT t.INDEX_NAME
      FROM user_indexes t
     where t.TABLE_NAME = 'TEST'
       and t.uniqueness = 'NONUNIQUE'
       and t.index_type = 'NORMAL';
  --先将原表索引 unusable 以及nologging,加快DML数据速度
  for ff in (SELECT t.INDEX_NAME, t.UNIQUENESS, t.index_type
               FROM user_indexes t
              where t.TABLE_NAME = 'TEST'
                and t.index_type = 'NORMAL') loop
    --将非唯一性约束索引 unusable 
    if ff.uniqueness = 'NONUNIQUE' then
      l_sqltext := 'alter index ' || ff.INDEX_NAME || ' unusable ';
    else
      --将唯一性约束索引 nologging
      --不能将唯一性约束unusable,因为会导致表插入不了数据
      l_sqltext := 'alter index ' || ff.INDEX_NAME || ' nologging';
    
    end if;
    execute immediate L_SQLTEXT;
  
  end loop;
  /*
  ---------------------------------
   此处省略对TEST表的DML处理SQL        
  
  ---------------------------------
  */
  --重建索引
  for ff in (SELECT text FROM TMP_VACHAR_LIST t) loop
    l_sqltext := 'alter index ' || ff.text ||
                 ' rebuild online parallel 8 nologging';
    execute immediate L_SQLTEXT;
  end loop;
end;

热门相关:我有无数神剑   校花之高手无敌   明尊   99次离婚:厉少,请低调   99次出墙:老公,情难自禁