您的位置:首页 > 数据库 > Oracle

oracle分区表

2016-02-21 10:15 513 查看
官方文档:http://docs.oracle.com/cd/E11882_01/server.112/e40540/schemaob.htm#CNCPT1514

1. oracle最大支持1024K-1个分区,列的数据类型为LONG或者LONG RAW的表不允许创建分区。CLOB和BCLOB可以。

 什么时候需要对表进行分区:

 ① 大于2GB的表

 ② 历史数据只是用来查询,而且不停在插入新数据的表

 1.1 range分区

   range分区是最常用的分区类型,通常用于对日期进行分区,必须声明values less than子句,maxvalue代表最大值。 

create table test_range_table(
ename varchar2(30),
deptno number,
hire_date date
) partition by range(hire_date)(
partition before_2014 values less than (to_date('2014-01-01','yyyy-mm-dd')),
partition before_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')),
partition before_forever values less than (maxvalue)
);


  如上SQL新建了分区表test_range_table,通过对hire_date分区将表分成了三个分区:before_2014(hire_date在2014年之前),before_2015(hire_date在2014和2015年之间),before_forever(hire_date在2015年之后).分区表以及分区可以通过user_tab_partitions,dba_tab_partitions,all_tab_partitions查询。

 1.2 list分区可以对看似无序的数据按照某种规则进行整理,list分布不支持对多列进行分区,单支持为一个分区设定多个不同的值。如果往list分区表插入未在list分区定义的值,会报错的,default关键字可以避免这个问题。对于分区表test_list_table,假设不指定other_region分区,执行

insert into test_list_table values('张三',10,'张三');


会报错:"ORA-14400:插入的分区关键字未映射到任何分区"

--list分区表
create table test_list_table(
ename varchar2(30),
deptno number,
region varchar2(30)
) partition by list(region)(
partition china_region values('china'),
partition japan_region values('japan'),
partition europe_region values('france','germany'),
partition other_region values(default)
)


 1.3 hash分区新建的时候只需要指定分区列和分区个数即可,也可以指定分区的表空间。

create table test_hash_table(first_name varchar2(30),
last_name varchar2(30),
hire_date date)
partition by hash(last_name)
partitions 4
store in (tb_01,tb_02,tb_03,tb_04);


 1.4 range-hash分区,子分区信息可以通过user_tab_subpartitions,all_tab_subpartitions,dba_tab_subpartitions查询。

--range-hash分区
create table test_range_hash_table(
first_name varchar2(30),
last_name varchar2(30),
hire_date date
) partition by range(hire_date)
subpartition by hash(last_name)
subpartition template(
subpartition sp1 ,
subpartition sp2,
subpartition sp3,
subpartition sp4)
(
partition before_2014 values less than (to_date('2014-01-01','yyyy-mm-dd')),
partition before_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')),
partition before_forever values less than (maxvalue)
)


  1.5 range-list分区

create table test_range_list_table(
ename varchar2(30),
region varchar2(30),
hire_date date
)
partition by range(hire_date)
subpartition by list(region)
subpartition template(
subpartition china_region values('china'),
subpartition japan_region values('japan'),
subpartition europe_region values('france','germany'),
subpartition other_region values(default)
)
( partition before_2014 values less than (to_date('2014-01-01','yyyy-mm-dd')),
partition before_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')),
partition before_forever values less than (maxvalue));


2. 分区索引

  分区索引分类两类global indexes(基于整个表) 和 local indexes(基于表的分区),通常来说OLTP系统应该使用global indexes,数据仓库或者DSS应该使用local indexes。可以按照如下顺序决定采用哪种分区索引:

  Step-1:如果分区列是被索引列的子集,用local index,结束;否则Step-2

  Step-2:如果索引唯一,用global index,结束;否则Step-3

  Step-3:如果更看重维护性能,用local index,结束;否则Step-4

  Step-4:如果是OLTP用户看重response time用global index;如果是数据仓库用户看重吞吐量用local index

  2.1 LOCAL PARTITIONED INDEX

    local index和表分区是一一对应的

    local nonprefixed index : 索引列为非分区列的简单索引,索引前置列为非分区列的复合索引,不一定允许分区修剪

    local prefixed index: 索引列为分区列的简单索引,索引前置列为分区列的复合索引,允许分区修剪

    local index的优点:

    ① 当一个分区的数据失效时,不会影响其他分区

    ② 当移动表分区或者数据被移出分区时,只有相关分区的索引需要被rebuilt,对global来说,所有的分区索引都要被rebuilt

    ③ 当基于时间点的恢复发生时,可以只恢复相关分区的索引,不需要rebuilit所有分区索引。 

create index test_range_table_local_n1 on test_range_table(hire_date) local;


  2.2 GLOBAL PARTITIONED INDEX

    global range partitioned index:基于范围的global index

    global hash partitioned index:基于hash的global index

    global index是独立于分区表的,假设表基于hire_date的分区为3个(before_2014,before_2015,before_forever),可以基于hire_date创建四个分区的global_index(before_2013,before_2014,before_2015,before_forever),global index也可以对不是分区列的column进行随意的分区。 

--global range index
--drop index test_range_table_local_n1
create index test_range_table_gl_range on test_range_table(hire_date)
global partition by range(hire_date)(
partition before_2013 values less than (to_date('2013-01-01','yyyy-mm-dd')),
partition before_2014 values less than (to_date('2014-01-01','yyyy-mm-dd')),
partition before_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')),
partition before_forever values less than (maxvalue)
)

--global hash index
--drop index test_range_table_gl_range;
create index test_range_table_gl_hash on test_range_table(hire_date)
global partition by hash(hire_date)
partitions 4;


  2.3 GLOBAL NONPARTITIONED INDEX

  2.4 关于分区索引

    可以通过user_ind_partitions,user_dba_partitions,user_all_partitions查询分区索引。

    只能给分区表建立local类型的位图索引。

    global index可以是唯一索引,只有当索引列是分区列的时候local index才可以是唯一索引。

    分区索引在OLTP系统中的应用:

    ① global index和unique local index性能更优

    ② 当存在对分区表的分区或者子分区维护时,local index表现更好

    ③ 索引单调增长的时候,hash-partitioned global index更好,因为大部分的索引插入都是在索引右侧。

    分区索引在DSS或者数据仓库中的应用:

    ① local index在数据加载或者分区维护的时候更方便

    ② local index可以并行的对多个索引分区进行扫描

3.分区对系统性能的提升

  3.1 PARTITION PRUNING(分区修剪)

    当谓词条件中包含分区列时,oracle会指定把不需要的分区剪掉。当对分区列施加函数时,分区修剪失效;同样,但对索引列施加函数是,索引失效,除非该索引是基于数据的。

  3.2 PARTITION-WISE JOINS

    当两个分区表做连接,连接列恰好是这个两个分区表的分区列,则连接操作会变成并发的进行多个分区和多个分区之间的连接操作???

  3.3 PARALLEL DML
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: