首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免移动分区时重新生成Oracle全局索引

如何避免移动分区时重新生成Oracle全局索引
EN

Stack Overflow用户
提问于 2016-02-09 12:45:17
回答 1查看 2K关注 0票数 4

定期地,我需要将分区从一个表中分离出来,并在不同的表空间中附加到另一个表。

伪流:

  • 循环每个表和过期的分区: 1.1在目标表中创建新的目标分区 1.2将分区移动到目标表空间 1.3将源分区转换为临时表 1.4具有目标分区的Exchange临时表 1.5删除源分区
  • 重新生成源表中的全局索引
  • 重建目标表中的全局索引

问题是,重建索引会使索引暂时不可用,在我的情况下,这是无法接受的支持实时应用程序的。

索引重建是一项昂贵的操作,避免这种情况的一种方法是执行异步全局索引维护,这使得全局索引成为孤儿,但仍然可以使用而无需任何重建。但是,孤立索引只能在分区删除和分区截断操作中启用。在上面的流程中,全局索引在Partition和Partition操作中不可用。最后一条语句中的分区拖放不能再强制执行孤立索引。

这是令人沮丧的,因为我知道分区最终会被删除,但我仍然有义务重建全球指数。你能建议无论如何避免索引重建吗?

注意:

  • 我可以在Partition和Partition子句中使用UPDATE全局索引子句,但是它很昂贵,在循环中将被多次调用。
  • 我可以将全局索引更改为本地索引,但这将对我们的应用程序产生更大的性能影响。此外,唯一索引将无法工作(分区键不涉及)。
EN

回答 1

Stack Overflow用户

发布于 2016-02-26 13:38:48

一种可能的方法是在TMP表中复制要从ACT中移动的分区(在所需的表空间中使用CTAS )和

  • 将TMP表与HIST表的分区和
  • 删除ACT表中的分区。

这种方法支持异步全局索引维护,但是一个星期的时间点是,移动是分两个步骤完成的,因此理论上可以同时看到分区或没有分区(取决于这两个步骤的每个顺序)。如果这是一个问题,一些额外的注意事项(例如锁定HIST表)。

这里是使用间隔PARTITONING的示例(表设置在下面)。

代码语言:javascript
复制
-- 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;

表设置

代码语言:javascript
复制
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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35292467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档