大数量的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;