分区好处:
1、提高数据可用性
2、由于数据中去除了大段,相应的减轻了管理的负担
3、改善某些查询的性能,但oltp系统,大多数情况下改善不大
4、可以把修改分布到多个单独的分区上,从而减少大容量OLTP系统上的竞争。
分类:
1)区间分区:指定数据区间来决定数据存储在哪个分区。
2)散列分区:在一个列(或多个列)上应用一个散列函数,行会按这个散列值放在某个分区中。
3)列表分区:指定一个离散值集,来数据存储在哪个分区。
4)组合分区:区间分区和散列分区的一种组合,或者是区间分区与列表分区的组合。通过组合分区,先对某些数据应用区间分区,再在区间中根据散列或列表来选择最后的分区。
1、区间分区
分区区间是按照严格小于某个值(less than)来指定的
JEL@JEL >create table t_range(range_key date,data varchar2(100))
2 partition by range (range_key)
3 (partition p1 values less than (to_date('2012/01/01','yyyy/mm/dd')) tablespace ts1,
4 partition p2 values less than (to_date('2013/01/01','yyyy/mm/dd')) tablespace ts2);
Table created.
JEL@JEL >insert into t_range values(to_date('2011/01/01','yyyy/mm/dd'),'abcd');
1 row created.
JEL@JEL >insert into t_range values(to_date('2012/02/02','yyyy/mm/dd'),'abcd');
1 row created.
JEL@JEL >commit;
Commit complete.
JEL@JEL >select * from t_range partition (p1);
RANGE_KEY
---------
DATA
--------------------------------------------------------------------------------
01-JAN-11
abcd
JEL@JEL >select * from t_range partition (p2);
RANGE_KEY
---------
DATA
--------------------------------------------------------------------------------
02-FEB-12
abcd
如果插入值不在任何区间内,则出错
JEL@JEL >insert into t_range values(to_date('2015/01/01','yyyy/mm/dd'),'abcd');
insert into t_range values(to_date('2015/01/01','yyyy/mm/dd'),'abcd')
*
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
JEL@JEL >alter table t_range add partition p3 values less than (maxvalue) tablespace ts3;
Table altered.
JEL@JEL >insert into t_range values(to_date('2015/01/01','yyyy/mm/dd'),'abcd');
1 row created.
JEL@JEL >select * from t_range partition (p3);
RANGE_KEY
---------
DATA
--------------------------------------------------------------------------------
01-JAN-15
abcd
2、散列分区
Oracle会对分区键应用一个散列函数,以此确定数据应当放在N 个分区中的哪一个分区中。因此不能控制一行最终会放在哪个分区中。分区数应该是2的幂,这样才能让数据在各个分区均匀分布。
JEL@JEL >create table t_hash(hash_key date,data varchar2(3))
2 partition by hash(hash_key)
3 (partition p1 tablespace ts1,
4 partition p2 tablespace ts2);
Table created.
JEL@JEL >insert into t_hash values(to_date('2010/12/31', 'yyyy/mm/dd'), 'AAA');
1 row created.
JEL@JEL >insert into t_hash values(to_date('2011/01/01', 'yyyy/mm/dd'), 'BBB');
1 row created.
JEL@JEL >insert into t_hash values(to_date('2012/01/01', 'yyyy/mm/dd'), 'CCC');
1 row created.
JEL@JEL >insert into t_hash values(to_date('2012/12/12', 'yyyy/mm/dd'), 'DDD');
1 row created.
JEL@JEL >select * from t_hash partition (p1);
HASH_KEY DAT
--------- ---
01-JAN-11 BBB
01-JAN-12 CCC
JEL@JEL >select * from t_hash partition (p2);
HASH_KEY DAT
--------- ---
12-DEC-12 DDD
31-DEC-12 AAA
3、列表分区
列表分区提供按照离散值来进行分区的功能。和区间分区类似,如果插入的分区键不在指定的集合中,会产生错误,可以使用VALUES(DEFAULT)子句来指定一个"others"区间。但是如果已经存在DEFAULT分区,就不能再往这个表增加分区了。
JEL@JEL >create table t_list(list_key varchar2(5), data varchar2(32))
2 partition by list(list_key) (
3 partition part_1 values ('east', 'south') tablespace ts1,
4 partition part_2 values ('west', 'north') tablespace ts2,
5 partition part_3 values (default) tablespace ts3
6 );
Table created.
JEL@JEL >insert into t_list values('east', 'AAA');
1 row created.
JEL@JEL >insert into t_list values('south', 'BBB');
1 row created.
JEL@JEL >insert into t_list values('west', 'CCC');
1 row created.
JEL@JEL >insert into t_list values('north', 'DDD');
1 row created.
JEL@JEL >insert into t_list values(null, 'EEE');
1 row created.
JEL@JEL >insert into t_list values('sdfs','FFF');
1 row created.
JEL@JEL >select * from t_list partition (part_1);
LIST_ DATA
----- --------------------------------
east AAA
south BBB
JEL@JEL >select * from t_list partition (part_2);
LIST_ DATA
----- --------------------------------
west CCC
north DDD
JEL@JEL >select * from t_list partition (part_3);
LIST_ DATA
----- --------------------------------
EEE
sdfs FFF
4、组合分区
组合分区区(composite partitioning)中,顶层分区机制总是区间分区。第二级分区机制可能是列表分区或散列分区。使用组合分区时,并没有分区段,而只有子分区段。分区本身并没有段(这就类似于分区表本身没有段)。数据物理的存储在子分区段上,分区成为一个逻辑容器。可以在分区上指定表空间,也可以在子分区上指定表空间。每个区间分区不需要有相同数目的子分区。
JEL@JEL >create table t_range_list(range_key date, list_key int, data varchar2(32))
2 partition by range (range_key)
3 subpartition by list (list_key) (
4 partition part_1 values less than (to_date('2011/01/01', 'yyyy/mm/dd')) (
5 subpartition part_1_sub_1 values (1,3,5,7) tablespace ts1,
6 subpartition part_1_sub_2 values (2,4,6,8) tablespace ts2),
7 partition part_2 values less than (to_date('2012/01/01', 'yyyy/mm/dd')) (
8 subpartition part_2_sub_1 values (1,3) tablespace ts1,
9 subpartition part_2_sub_2 values (5,7) tablespace ts2,
10 subpartition part_2_sub_3 values (2,4,6,8) tablespace ts3)
11 );
Table created.
JEL@JEL >insert into t_range_list values(to_date('2010/12/31','yyyy/mm/dd'), 1, 'AAA');
1 row created.
JEL@JEL >insert into t_range_list values(to_date('2010/12/31','yyyy/mm/dd'), 2, 'BBB');
1 row created.
JEL@JEL >select * from t_range_list partition(part_1);
RANGE_KEY LIST_KEY DATA
--------- ---------- --------------------------------
31-DEC-10 1 AAA
31-DEC-10 2 BBB
JEL@JEL >select * from t_range_list subpartition(part_1_sub_1);
RANGE_KEY LIST_KEY DATA
--------- ---------- --------------------------------
31-DEC-10 1 AAA
行移动
如果修改用于确定分区的列,并且修改会导致行跨分区移动,那么只有当表启用了行移动这个修改才能成功。(跨分区移动会导致行的ROWID改变)
使用下面语句启用行移动。
alter table tablename enable row movement;
否则,会得到一个错误,
ORA-14402: updating partition key column would cause a partition change
行移动的开销比正常的update昂贵的多,所以,要避免构建频繁修改分区键导致行移动的系统。
小结
建议:如果可以按某个属性自然的对数据完成区间分区,那么就使用区间分区表,而不是散列或列表分区。散列和列表分区在分区消除方面都不如区间分区有用。如果所得到的区间分区太大,不能很好的管理,或者你想使用并行DML功能或者对一个区间分区使用并行索引扫描,则建议在区间分区中在使用散列或列表分区
以下是关于何时应该对表进行分区的一些建议:
1.如果表数据量超过 2GB,就应该考虑进行分区。
2.如果表中包含历史数据,且新数据会被添加到最新的表空间中。典型的例子是一种历史表,其中只有当前月份的数据可以被修改,而其他十一个月的数据为只读。
相关数据字典
user_tab_partitions: 查看表分区信息
user_tab_subpartitions : 查看表子分区信息
user_part_key_columns: 查看分区键
user_subpart_key_columns: 查看子分区键
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29337971/viewspace-1064175/
,如需转载,请注明出处,否则将追究法律责任。