ITPub博客

首页 > 数据库 > Oracle > 表分区

表分区

原创 Oracle 作者:jelephant 时间:2013-12-24 21:15:14 0 删除 编辑

分区好处:
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/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: LOB类型
下一篇: 索引分区(一)
请登录后发表评论 登录
全部评论

注册时间:2013-12-07

  • 博文量
    143
  • 访问量
    681877