【优化】交换分区

交换分区Exchange partition:提供了一种方式,让你在表与表或分区与分区之间迁移数据,注意不是将表转换成分区或非分区的形式,而仅只是迁移表中数据(互相迁移),由于其号称是采用了更改数据字典的方式,因此效率最高(几乎不涉及io操作)Exchange partition适用于所有分区格式,你可以将数据从分区表迁移到非分区表,也可以从非分区表迁移至分区表

 

语法:alter table tbname1 exchange partition/subpartition ptname with table tbname2;

   含义: 将表tbname1中的ptname分区与表tbname2进行交换

   实质:只是交换了名称,类似于指针的指向的内容发生了变化。

 

注意:在将未分区表的数据迁移到分区表中时,可能出现ora-14099的错误,虽然可以用without validation去解决,但是此时进入分区表的数据可能不符合分区规则。所以without   validation一定要慎用。

  l. 涉及交换的两表之间表结构必须一致,除非附加with validation子句;

  2. 如果是从非分区表向分区表做交换,非分区表中的数据必须符合分区表中指定分区的规则,除非附加without validation子句;

  3. 如果从分区表向分区表做交换,被交换的分区的数据必须符合分区规则,除非附加without validation子句;

  4. Global索引或涉及到数据改动了的global索引分区会被置为unusable,除非附加update indexes子句。

提示:一旦附加了without validation子句,则表示不再验证数据有效性,因此指定该子句时务必慎重。

应用:可以使用在分区表导出时,建立临时表与分区进行交换(这样临时表内容指向原来的分区,并且是自包含的),然后进行表空间的迁移。

 

 

--创建分区表

SCOTT@ORA11GR2>create table test_par

  2  (

  3  nid number(10) constraint pk_test_p primary key,

  4  idcard varchar2(18),

  5  pdd date not null

  6  )

  7  partition by range (pdd)

  8  (

  9  partition par_2000 values less than (to_date('2001-01-01','yyyy-mm-dd')),

 10  partition par_2001 values less than (to_date('2002-01-01','yyyy-mm-dd')),

 11  partition par_2002 values less than (to_date('2003-01-01','yyyy-mm-dd')),

 12  partition part_maxvalue values less than (maxvalue)

 13  );

 

Table created.

--创建全局索引

SCOTT@ORA11GR2>create index idx_test_par on test_par(idcard);

 

Index created.

--插入几条测试数据,分别存放在不同的分区中

SCOTT@ORA11GR2>insert into test_par values(500,'2000',to_date('20000101','yyyymmdd'));

 

1 row created.

 

SCOTT@ORA11GR2>insert into test_par values(501,'2001',to_date('20010201','yyyymmdd'));

 

1 row created.

 

SCOTT@ORA11GR2>insert into test_par values(502,'2002',to_date('20020301','yyyymmdd'));

 

1 row created.

 

SCOTT@ORA11GR2>commit;

 

Commit complete.

 

--此时索引的状态为有效的

SCOTT@ORA11GR2>select INDEX_NAME,STATUS from user_indexes where index_name='IDX_TEST_PAR';

 

INDEX_NAME                     STATUS

------------------------------ --------

IDX_TEST_PAR                   VALID

--创建与分区表结构相同的表

SCOTT@ORA11GR2>create table test

  2  (

  3  nid number(10) constraint pk_test primary key,

  4  idcard varchar2(18),

  5  pdd date not null

  6  );

 

Table created.

 

--插入数据:

SCOTT@ORA11GR2>insert into test select rownum,rpad(rownum,18,'0'),to_date('20020101','yyyymmdd')+rownum from dual connect by rownum<=100;

 

100 rows created.

 

SCOTT@ORA11GR2>commit;

 

Commit complete.

 

SCOTT@ORA11GR2>select min(pdd),max(pdd) from test;

 

MIN(PDD)            MAX(PDD)

------------------- -------------------

2002-01-02 00:00:00 2002-04-11 00:00:00

 

SCOTT@ORA11GR2>select count(*) from test;

 

  COUNT(*)

----------

       100

 

--进行交换分区动作:

SCOTT@ORA11GR2>alter table test_par exchange partition par_2002 with table test;

 

Table altered.

 

--验证

--此时test表中,只有一条记录了。即原来2002分区中的数据。

SCOTT@ORA11GR2>select count(*) from test;

 

  COUNT(*)

----------

         1

 

SCOTT@ORA11GR2>select * from test;

 

       NID IDCARD             PDD

---------- ------------------ -------------------

       502 2002               2002-03-01 00:00:00

 

--验证看到分区表已经是102条记录

SCOTT@ORA11GR2>select count(*) from test_par;

 

  COUNT(*)

----------

       102

 

--其中我们交换的par_2002分区为100条记录

SCOTT@ORA11GR2>select count(*) from test_par partition (par_2002);

 

  COUNT(*)

----------

       100

 

--此时索引已失效,因为是全局索引;

SCOTT@ORA11GR2>select INDEX_NAME,STATUS from user_indexes where index_name='IDX_TEST_PAR';

 

INDEX_NAME                     STATUS

------------------------------ --------

IDX_TEST_PAR                   UNUSABLE

 

——重建全局索引

SCOTT@ORA11GR2>alter index idx_test_par rebuild;

 

Index altered.

 

SCOTT@ORA11GR2>select INDEX_NAME,STATUS from user_indexes where index_name='IDX_TEST_PAR';

 

INDEX_NAME                     STATUS

------------------------------ --------

IDX_TEST_PAR                   VALID

 




请使用浏览器的分享功能分享到微信等