Oracle 表分区机制介绍

      一. 概念

      一个表被分成了很多个独立的分区,那么每一个分区应该存储哪些数据,这就是表分区机制要解决的问题。

      二. 表分区机制概述

      目前oracle中有四种分区机制:

      1. 区间分区:可以指定应当存储在一起的数据区间。例如,时间戳在Jan-2005内的所有记录都存储在分区1中,时间戳在Feb-2005内的所有记录都存储在分区2中,依此类推。

      2. 散列分区:这是指在一个列(或多个列)上应用一个散列函数,行会按这个散列值放在某个分区中。具有很大随机性,你不知道数据会被散列到哪个分区中去,但是一般每个分区存储的数据都差不多大小。

      3. 列表分区:指定一个离散值集,来确定应当存储在一起的数据。例如,可以指定STATUS列值在(’A’,’M’,’Z’)中的行放在分区1中,STATUS值在(‘D’,’P’,’Q’)中的行放在分区2中,依此类推。

      4. 组合分区:这是区间分区和散列分区的一种组合,或者是区间分区与列表分区的组合。通过组合分区,你可以先对某些数据应用区间分区,再在区间中根据散列或列表来选择最后的分区。

      三. 各种分区机制介绍

      1. 区间分区

       建表语句示例:(用得最频繁)

CREATE TABLE range_example
 ( range_key_column date ,
 data varchar2(20)
 )
 PARTITION BY RANGE (range_key_column)
 ( PARTITION part_1 VALUES LESS THAN
 (to_date('01/01/2005','dd/mm/yyyy')),
 PARTITION part_2 VALUES LESS THAN
 (to_date('01/01/2006','dd/mm/yyyy')),
 PARTITION part_3 VALUES LESS THAN
 (MAXVALUE)
 )

      这样,日期小于2005年的数据放在part_1分区,日期是2005年的数据放在part_2分区,日期大于2005年的数据放在part_3分区。

      2. 散列分区

      对一个表执行散列分区时,oracle会对分区键运用一个散列函数,依此确定数据应该放在N个分区中哪一个。Oracle建议N是2的一个幂(2,4,8,16等),从而得到最佳的总体分布。

      散列分区是为了使数据尽可能均匀地分布在多个不同的分区上,选择分区键非常重要,如果选得不好,数据就会分布不均。建议分区键应该是唯一的列(比如主键)或者唯一的一组列(多列组成的主键)。 假如你选择的分区键只可能有4个相异的值,并使用2个分区,那么可能将所有的数据散列到同一分区上。

     创建散列分区表示例:

CREATE TABLE hash_example
 ( hash_key_column date,
 data varchar2(20)
 )
 PARTITION BY HASH (hash_key_column)
 ( partition part_1 tablespace p1,
 partition part_2 tablespace p2
 )

      3. 列表分区

      列表分区(list partitioning)是Oracle9i Release 1的一个新特性。它提供了这样一种功能,可以根据离散的值列表来指定一行位于哪个分区。如果能根据某个代码来进行分区(如州代码或区代码),这通常很有用。例如,你可能想把Maine州(ME)、New Hampshire州(NH)、Vermont州(VT)和Massachusetts州(MA)中所有人的记录都归至一个分区中,因为这些州相互之间挨得很近,而且你的应用按地理位置来查询数据。类似地,你可能希望将Connecticut州(CT)、Rhode Island州(RI)和New York州(NY)的数据分组在一起。

     SQL代码示例:

 create table list_example
 ( state_cd varchar2(2),
 data varchar2(20)
 )
 partition by list(state_cd)
 ( partition part_1 values ( 'ME', 'NH', 'VT', 'MA' ),
 partition part_2 values ( 'CT', 'RI', 'NY' )
)

    这样创建之后,如果想插入不在这七个地方的数据就会报错。比如:insert into list_example values ( 'VA', 'data' );这个时候应该加一个默认分区,SQL如下:

alter table list_example
 add partition
 part_3 values ( DEFAULT );

    但是表一旦有了默认分区,不可以继续添加其他分区了,因为默认分区可能包含其他分区的数据。

    4. 组合分区

     其实就是上述分区的组合,区间分区加散列分区,区间分区加列表分区。就是区间分区之后,感觉每一个分区数据量还是很大,继续在分区上进行分区。代码示例如下:

     区间分区加散列分区

CREATE TABLE composite_example
 ( range_key_column date,
 hash_key_column int,
 data varchar2(20)
 )
  PARTITION BY RANGE (range_key_column)
 subpartition by hash(hash_key_column) subpartitions 2
 (
 PARTITION part_1
 VALUES LESS THAN(to_date('01/01/2005','dd/mm/yyyy'))
 (subpartition part_1_sub_1,
 subpartition part_1_sub_2
 ),
 PARTITION part_2
 VALUES LESS THAN(to_date('01/01/2006','dd/mm/yyyy'))
 (subpartition part_2_sub_1,
 subpartition part_2_sub_2
 )
 )

     区间分区加列表分区

CREATE TABLE composite_range_list_example
 ( range_key_column date,
 code_key_column int,
 data varchar2(20)
 )
 PARTITION BY RANGE (range_key_column)
 subpartition by list(code_key_column) 697 / 860
 (
 PARTITION part_1
 VALUES LESS THAN(to_date('01/01/2005','dd/mm/yyyy'))
 (subpartition part_1_sub_1 values( 1, 3, 5, 7 ),
 subpartition part_1_sub_2 values( 2, 4, 6, 8 )
 ),
 PARTITION part_2
 VALUES LESS THAN(to_date('01/01/2006','dd/mm/yyyy'))
 (subpartition part_2_sub_1 values ( 1, 3 ),
 subpartition part_2_sub_2 values ( 5, 7 ),
 subpartition part_2_sub_3 values ( 2, 4, 6, 8 )
 )
 )

    总之,,如果可以按某个属性自然地对数据完成区间分区,就应该使用区间分区,而不是散列分区或列表分区。散列和列表分区能提供分区的许多突出优点,但是在分区消除方面都不如区间分区有用。如果所得到的区间分区太大,不能很好地管理;或者如果你想使用所有PDML功能或对一个区间分区使用并行索引扫描,则建议在区间分区中再使用散列或列表分区。

猜你喜欢

转载自liwenshui322.iteye.com/blog/1709104
今日推荐