我需要定期从一个表中分离分区并附加到不同表空间中的另一个表. 伪流: 循环每个表和过期的分区: 1.1在目标表中创建新的目标分区 1.2将分区移动到目标表空间 1.3将源分区交换为临
伪流:
>循环每个表和过期的分区:
1.1在目标表中创建新的目标分区
1.2将分区移动到目标表空间
1.3将源分区交换为临时表
1.4使用目标分区交换临时表
1.5删除源分区
>在源表中重建全局索引
>在目标表中重建全局索引
问题是,重建索引使索引临时不可用,在我的情况下支持实时应用是不可接受的.
索引重建是一项昂贵的操作,避免这种情况的一种方法是强制实施异步全局索引维护,这使得全局索引孤立但仍然可以在不进行任何重建的情况下使用.但是,只能在Partition Drop和Partition Truncate操作中启用孤立索引.在上面的流程中,全局索引在分区移动和分区Exchange操作中呈现为不可用.最后一个语句中的分区删除不再强制执行孤立索引.
这是令人费解的因为我知道分区最终会被删除,但我仍然不得不重建全局索引.无论如何你能建议避免索引重建吗?
注意:
>我可以在Partition Move和中使用UPDATE GLOBAL INDEXES子句
分区交换条款,但它是昂贵的,它会
在循环中多次调用.
>我可以将全局索引更改为本地索引,但这将有
对我们的应用产生更大的性能影此外,独特
index不起作用(不涉及分区键).
>将TMP表与HIST表的分区交换
>删除ACT表中的分区.
这种方法启用了异步全局索引维护,但是在某种程度上,周点是移动分两步完成,因此理论上可能会有查询同时看到分区或没有分区(取决于两个步骤的顺序).如果这是一个问题,需要额外注意(例如锁定HIST表).
这里使用INTERVAL PARTITONING的示例(表格设置如下).
-- step 1 copy the partition to be moved from ACT table create table tmp as select * from t_act partition FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')); -- step 2 allocate partition in HIST table LOCK TABLE t_hist PARTITION FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) IN SHARE MODE; -- step 3 publish the copy in HIST table and DROP the ACT partition ALTER TABLE t_hist EXCHANGE PARTITION FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) WITH TABLE tmp INCLUDING INDEXES; alter table t_act drop partition FOR (TO_DATE('2016-02-21', 'YYYY-MM-DD')) UPDATE INDEXES;
表设置
drop TABLE t_act; CREATE TABLE t_act (id number, transaction_date DATE not null, vc_pad VARCHAR2(100) ) PARTITION BY RANGE (transaction_date) INTERVAL (NUMTODSINTERVAL(1,'DAY')) ( PARTITION P_01 VALUES LESS THAN (TO_DATE('2016-02-22', 'YYYY-MM-DD') ), PARTITION P_02 VALUES LESS THAN (TO_DATE('2016-02-23', 'YYYY-MM-DD') ) ); ALTER TABLE t_act ADD CONSTRAINT t_act_pk PRIMARY KEY (id); create index t_act_ix1 on t_act(transaction_date); drop TABLE t_hist; CREATE TABLE t_hist (id number, transaction_date DATE not null, vc_pad VARCHAR2(100) ) PARTITION BY RANGE (transaction_date) INTERVAL (NUMTODSINTERVAL(1,'DAY')) ( PARTITION P_01 VALUES LESS THAN (TO_DATE('2016-02-20', 'YYYY-MM-DD') ), PARTITION P_02 VALUES LESS THAN (TO_DATE('2016-02-21', 'YYYY-MM-DD') ) ); insert into t_act select rownum, TO_DATE('2016-02-21', 'YYYY-MM-DD') ,'TEST' from dual connect by level <= 100000; commit;