直白的说就是迁移数据。迁移数据的方式很多,为什么要使用exchangepartition的方式呢,表急,听三思慢慢道来。

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

其语法很简单:altertabletbname1exchangepartition/subpartitionptnamewithtabletbname2;

Exchangepartition迁移的方式也很有意思,言语表达怕大家听不明白,下面直接通过示例来表达:


借用前文中创建的空分区表:t_partition_range,并插入几条记录

JSSWEB>createtablet_partition_range(idnumber,namevarchar2(50))
2partitionbyrange(id)(
3partitiont_range_p1valueslessthan(10)tablespacetbspart01,
4partitiont_range_p2valueslessthan(20)tablespacetbspart02,
5partitiont_range_p3valueslessthan(30)tablespacetbspart03,
6partitiont_range_pmaxvalueslessthan(maxvalue)tablespacetbspart04
7);


表已创建。


JSSWEB>insertintot_partition_rangevalues(11,'a');

已创建1行。

JSSWEB>insertintot_partition_rangevalues(12,'b');

已创建1行。


JSSWEB>insertintot_partition_rangevalues(13,'c');

已创建1行。


JSSWEB>commit;

提交完成。


再创建一个非分区表,结构与t_partition_range相同

JSSWEB>createtablet_partition_range_tmp(idnumber,namevarchar2(50));

表已创建。


执行交换分区(我们知道刚插入到range分区表的数据都在分区t_range_p2中,因此这里指定交换该分区)

JSSWEB>altertablet_partition_rangeexchangepartitiont_range_p2
2withtablet_partition_range_tmp;

表已更改。


看看效果如何

JSSWEB>select*fromt_partition_rangepartition(t_range_p2);

未选定行


JSSWEB>select*fromt_partition_range_tmp;

IDNAME
------------------------------------------------------------
11a
12b
13c

记录成功交换到未分区的表中。


我们再执行一次exchangepartition的命令,看看又会发生什么呢

JSSWEB>select*fromt_partition_rangepartition(t_range_p2);

IDNAME
------------------------------------------------------------
11a
12b
13c

JSSWEB>select*fromt_partition_range_tmp;

未选定行

又交换回来了,有点儿意思。


再做个更加明确的测试,我们往未分区的表中加入一些记录后再执行exchangepartition,看看会发生什么呢:

JSSWEB>insertintot_partition_range_tmpvalues(15,'d');

已创建1行。


JSSWEB>insertintot_partition_range_tmpvalues(16,'e');

已创建1行。


JSSWEB>insertintot_partition_range_tmpvalues(17,'d');

已创建1行。


JSSWEB>altertablet_partition_rangeexchangepartitiont_range_p2
2withtablet_partition_range_tmp;

表已更改。


JSSWEB>select*fromt_partition_rangepartition(t_range_p2);

IDNAME
------------------------------------------------------------
15d
16e
17d

JSSWEB>select*fromt_partition_range_tmp;

IDNAME
------------------------------------------------------------
11a
12b
13c

这就是前面所说的,互相交换的意思~~


注意:

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

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

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

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

提示:

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

例如:

JSSWEB>insertintot_partition_range_tmpvalues(8,'g');


已创建1行。

JSSWEB>altertablet_partition_rangeexchangepartitiont_range_p2
2withtablet_partition_range_tmpwithoutvalidation;

表已更改。


JSSWEB>select*fromt_partition_rangepartition(t_range_p2);

IDNAME
------------------------------------------------------------
11a
12b
13c
8g

虽然新插入的记录并不符合t_range_p2分区的范围值,但指定了withoutvalidation后,数据仍然转换成功。