Oracle中普通表转换为分区表常用的方法
2017-02-27 19:34
465 查看
在 Oracle 几年的学习中, 做了很多的实验,也遇到了很多的问题, 在这个过程中,积累了一些学习文档。 因为太多,不便于查阅。
根据自己对 Oracle 的理解以及日常工作中遇到的情况并进行了一些整理,方便自己的查看。 这些文档中有很多内引用借鉴了前辈们的资料和 google 上的
一些信息。 在这里引用的内容也是完全出于学习,没有其他用途,如有侵犯到版权的问题,请联系我。 我将删除这些信息。对数据库这块也是在不断的学习,
对 Oracle 的理解也是在不断的变化。 在这个过程中,难免有理解错误的地方, 或者内容上遗漏的,如果发现了问题, 烦邮件给我,我会虚心的学习,并更新该文档。
接下来我来通过实验方法将普通表转换成分区表。
1. Insert with a subquery method
2. Partition exchange method
3. Export/import method
1.插入: Insert with a subquery method
这种方法就是使用 insert 来实现。 当然在创建分区表的时候可以一起插入数据,也可以创建好后在insert 进去。
这种方法采用DDL语句,不产生UNDO,
只产生少量 REDO,建表完成后数据已经在分布到各个分区中。
实验一:create table interval_wjh
partition by range (hire_date)
interval ( numtoyminterval (1, 'month') )
(partition part1
values less than (to_date ('02/14/2012', 'mm/dd/yyyy')))
as
select id, time_fee from test_table;
2.交换分区 Partition exchange method
这种方法只是对数据字典中分区和表的定义进行了修改,没有数据的修改或
复制,效率最高。适用于包含大数据量的表转到分区表中的一个分区的操作。尽
量在闲时进行操作。
交换分区的操作步骤如下:
1. 创建分区表,假设有 2 个分区,P1,P2.
2. 创建表 A 存放 P1 规则的数据。
3. 创建表 B 存放 P2 规则的数据。
4. 用表 A 和 P1 分区交换, 把表 A 的数据放到到 P1 分区
5. 用表 B 和 p2 分区交换, 把表 B 的数据存放到 P2 分区
实验二:
创建分区表:
sql> create table P_p
2 (id number,time date)
3 partition by range(time)
4 (
5 partition p1 values less than (to_date('2012-08-12', 'yyyy-mm-dd')),
6 partition p2 values less than (to_date('2013-11-22', 'yyyy-mm-dd'))
7 );
表已创建。
创建 2 个分别对应分区的基表:
SQL> CREATE TABLE P_p1 as SELECT employee_id,hire_date FROM test_table WHERE
hire_date<TO_DATE('2010-09-1', 'YYYY-MM-DD');
表已创建。
CREATE TABLE P_p2 as SELECT employee_id,hire_date FROM test_table WHERE
time_fee<TO_DATE('2010-11-1', 'YYYY-MM-DD') and
time_fee>TO_DATE('2010-09-1', 'YYYY-MM-DD');
表已创建。
将2个基表与2个分区进行交换:
SQL> alter table P_p exchange partition p1 with table dba_p1;
表已更改。
SQL> alter table P_p exchange partition p2 with table dba_p2;
表已更改
分区表的其他操作
添加新的分区
添加新的分区有 2 中情况:
(1) 原分区里边界是 maxvalue 或者 default。 这种情况下,我们需要把边界分
区 drop 掉,加上新分区后,在添加上新的分区。 或者采用 split,对边界分区进
行拆分。
(2) 没有边界分区的。 这种情况下,直接添加分区就可以了。
以边界分区添加新分区示例:
(1) 分区表和索引的信息如下:
SQL> create table David
2 (
3 id varchar2(15 byte) not null,
4 areacode varchar2(4 byte)
5 )
6 partition by list (areacode)
7 (
8 partition t_list536 values ('536') tablespace TBS1,
9 partition p_other values (default)tablespace TBS2
10 );
表已创建。
SQL> create index David_id on David(id)
2 local (
3 partition t_list556 tablespace icd_service,
4 partition p_other tablespace icd_service
5 );
索引已创建。
(2) 插入几条测试数据:
SQL> insert into custaddr values('1','556');
已创建 1 行。
SQL> insert into custaddr values('2','551');
已创建 1 行。
SQL> insert into custaddr values('3','555');
已创建 1 行。
SQL> commit;
提交完成。
删除 default 分区
sql> alter table David drop partition p_other;
表已更改。
添加新分区
SQL> alter table David add partition t_list551 values('551') tablespace TBS1;
表已更改。
添加 default 分区
SQL> alter table David add partition p_other values (default) tablespace
TBS2;
表已更改。
select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
CUSTADDR T_LIST556
CUSTADDR T_LIST551
CUSTADDR P_OTHER
对于局部索引, oracle 会自动增加一个局部分区索引。验证一下:
sql> select owner,index_name,table_name,partitioning_type from dba_part_indexes
where index_name='ix_custaddr_id';
owner index_name table_name
icd ix_custaddr_id custaddr
sql> select index_owner,index_name,partition_name from dba_ind_partitions where
index_name='ix_custaddr_id';
index_owner index_name partition_name
------------------------------ ------------------------------ ------------------
icd ix_custaddr_id p_other
icd ix_custaddr_id t_list551
icd ix_custaddr_id t_list556
split 分区拆分
在上节中,我们说明了可以使用 split 的方式来添加分区。 这里我们用 split
方法继续上面的实验。
sql> alter table david split partition p_other values('552') into (partition t_list552
tablespace TBS1, partition p_other tablespace TBS2);
表已更改。
注意:这里红色的地方,如果是 Range 类型的,使用 at, List 使用 Values。
SQL> select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
-----------------
4000
------------- ------------------------------
CUSTADDR T_LIST556
CUSTADDR T_LIST551
CUSTADDR T_LIST552
CUSTADDR P_OTHER
SQL> select index_owner,index_name,partition_name from dba_ind_partitions
where index_name='DAVID_ID';
index_owner index_name partition_name
------------------------------ ------------------------------ ------------------
icd ix_custaddr_id p_other
icd ix_custaddr_id t_list551
icd ix_custaddr_id t_list552
icd ix_custaddr_id t_list556
注意:分区表会自动维护局部分区索引。全局索引会失效,需要进行 rebuild。
合并分区 Merge
相邻的分区可以 merge 为一个分区,新分区的下边界为原来边界值较低的分区,上边界为原来边界值较高的分区, 原先的局部索引相应也会合并,全局索引
会失效,需要 rebuild。
alter table custaddr merge partitions t_list552,p_other into partition p_other;
表已更改。
SQL> select index_owner,index_name,partition_name from dba_ind_partitions
where index_name='CUSTADDR_ID';
index_owner index_name partition_name
-------------------- ------------------------------ ------------------
icd custaddr_id p_other
icd custaddr_id t_list551
icd custaddr_id t_list556
SQL> select table_name,partition_name from user_tab_partitions where
table_name='CUSTADDR';
table_name partition_name
------------------------------ ------------------------------
david t_list556
david t_list551
david p_other
移动分区
SQL> alter table david move partition P_OTHER tablespace system;
表已更改。
SQL> alter table david move partition P_OTHER tablespace icd_service;
表已更改。
注意: 分区移动会自动维护局部分区索引, oracle 不会自动维护全局索引,所
以需要我们重新 rebuild 分区索引,具体需要 rebuild 哪些索引,可以通过
dba_part_indexes,dba_ind_partitions 去判断。
SQL> Select index_name,status From user_indexes Where
table_name='CUSTADDR';
INDEX_NAME STATUS
------------------------------ --------
IX_CUSTADDR_ID N/A
Truncate 分区
SQL> select * from david partition(T_LIST556);
ID AREA
--------------- ----
1 556
SQL> alter table david truncate partition(T_LIST556);
表被截断。
SQL> select * from david partition(T_LIST556);
未选定行
Truncate 相对 delete 操作很快,数据仓库中的大量数据的批量数据加载可能
会有用到; 截断分区同样会自动维护局部分区索引,同时会使全局索引 unusable,
需要重建
Drop 分区
alter table david drop partition T_LIST551;
表已更改。
SQL> select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
CUSTADDR T_LIST556
CUSTADDR P_OTHER
同样会自动维护局部分区索引,同时会使全局索引 unusable,需要重建
相关文章推荐
- ORACLE普通表转换成分区表的方法及代码
- ORACLE 普通表转换成分区表(在线重定义)
- ORACLE普通表转换成分区表
- day13_普通表转换成分区表——oracle学习之bulk collect用法
- ORACLE普通表转换成分区表(在线重定义)
- oracle 11.2 普通表转换为分区表的常见方法
- ORACLE 普通表转换成分区表(在线重定义)
- 普通表向分区表转换的几种方法(转载yangtingkun blog)
- oracle普通表转化为分区表的方法
- ORACLE普通表转换成自动分区表
- Oracle 普通表与分区表转换
- Oracle普通表转分区表的几种方法
- ORACLE 普通表转换成分区表(在线重定义) --转帖
- 普通表向分区表转换的几种方法(转载yangtingkun blog)
- Oracle 分区表的新增、修改、删除、合并,普通表转分区表方法
- ORACLE 普通表转换成分区表(在线重定义)
- Oracle普通表->分区表转换(9亿数据量)
- 普通表向分区表转换的几种方法(转载yangtingkun blog)
- Oracle 在线重定义(将普通堆表转换成分区表)
- 普通表向分区表转换的几种方法(转载yangtingkun blog)