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

ORACLE:分区表range,hash,list

2015-07-29 20:15 676 查看
对表数据进行水平分割的一种手段!

降低I/O

分散I/O

基本概念:把一个大表分成几个部分

分区的方式:

range

如上面的清单表,按照时间范围进行分区

好处:

可以分散IO,不同的分区可以放在不同的表空间上。

如有的表是按照手机号码的后两位分区,这个表就有100个分区,可以把IO分散到100个不同的segment上。

可靠性

一个分区故障,不会影响其它的分区。可以建立再不同的表空间上,然后再集合起来用,有点像lvm。

创建管理range分区

create table t_range( hiredate date,id number(10)) partition by range(hiredate)

(

partition p1 values less than (to_date('2010-01-01','yyyy-mm-dd')),

partition p2 values less than (to_date('2014-01-01','yyyy-mm-dd'))

);

SQL> insert into t_range values (to_date('2008-01-01','yyyy-mm-dd'),1);

SQL> insert into t_range values (to_date('2009-01-01','yyyy-mm-dd'),2);

SQL> insert into t_range values (to_date('2010-01-01','yyyy-mm-dd'),3);

SQL> insert into t_range values (to_date('2011-01-01','yyyy-mm-dd'),4);

SQL> insert into t_range values (to_date('2012-01-01','yyyy-mm-dd'),5);

这几条记录insert完成后,p1里面有几条记录,p2分区里面有几条记录

SQL> select * from t_range partition(p1);

HIREDATE ID

--------- ----------

01-JAN-08 1

01-JAN-09 2

2条

seleSQL> select * from t_range partition(p2);

HIREDATE ID

--------- ----------

01-JAN-10 3

01-JAN-11 4

01-JAN-12 5

3条

如果我insert一条分区关键字中没有的记录呢?、

INSERT INTO t_range VALUES (TO_DATE('2017-02-02','YYYY-MM-DD'),6);

ERROR at line 1:

ORA-14400: inserted partition key does not map to any partition

报错,为什么??

解决这个问题两个方式

1、添加非最大分区

alter table t_range add partition p3 values less than (to_date('2018-01-01','yyyy-mm-dd'));

当然,也可以给他一个最大分区

2、添加最大分区

alter table t_range add partition p_max values less than (maxvalue); 添加最大分区

问题,有了最大分区后,如果我还想划分分区呢?比如还想要p4

alter table t_range add partition p4 values less than (to_date('2020-01-01','yyyy-mm-dd'));

报错

添加分区的要求,后面的分区必须要大于最后一个分区,现在表中的最后一个分区的值是maxvalue,还能添加吗?

3、split 分区:

alter table t_range split partition p_max

at (to_date('2020-01-01','yyyy-mm-dd')) --at后面加条件,默认是less than

into (partition p4,partition p_max) --into后面是分区,p_4是新劈的分区,就相当于把p_max分区来一刀,左边的叫p4,右边的叫p_max

/

注意:1、生产环境中及时add分区

在生产环境中要注意的是,在没有最大分区一定要注意检查分区范围。 如,你的分区只是在2015年,那么到了2016年的1月1日的时候你的业务就崩溃了。。。 移动故障

2、split分区要注意max分区的数据量情况

注意的第二点:有的时候有最大分区,但是由于某些原因很多数据匹配不到分区就insert到了最大分区中,如果后面要进行修复,如split的例子,要尽量保证max分区中的数据较少,否则会导致split的时间很长影响业务,alter table加的锁是6级别的锁啊!! 方法可以是使用expdp把max分区中的数据导出来,spilt后在impdp导入进去

hash

为了解决range 中数据不均匀的问题,有的时候用户是密集查询某个分区的数据

能不能有一个方法,把分区均匀的分到不同的地方??

hash 分区的特定:

1、更好的办法DML

why 已经把数据均匀的分开了,避免了热点块热点盘的问题

2、分区自动管理

根据 partition key oracle自动决定你放到那个分区中

3、hash分区的个数最好是2的幂次方个

缺点:range能精确的把某一行分到某一个分区上,hash却不能

create tablespace ts1 datafile '/oradata/vicdb/ts1.dbf' size 30m autoextend off;

create tablespace ts2 datafile '/oradata/vicdb/ts2.dbf' size 30m autoextend off;

create table t_hash (hiredate date,id number(10)) partition by hash(hiredate)

( partition p1 tablespace ts1,

partition p2 tablespace ts2

);

--insert 数据

insert into t_hash values (to_date('2008-01-01','yyyy-mm-dd'),1);

insert into t_hash values (to_date('2009-01-01','yyyy-mm-dd'),2);

insert into t_hash values (to_date('2010-01-01','yyyy-mm-dd'),3);

insert into t_hash values (to_date('2011-01-01','yyyy-mm-dd'),4);

insert into t_hash values (to_date('2012-01-01','yyyy-mm-dd'),5);

--验证数据平均分布

select * from t_hash partition(p1);

select * from t_hash partition(p2);

hash分区的分区消除

注意在hash分区中,对于不等值连接,如> <等,分区消除不可用,也就是说会扫描所有的分区。

比如,大于xx就可能意味结果不止一行,对于结果不止一行的情况,无法判断那些结果是否在同一个分区(range可以判断,因为他是有序的)

SQL> select * from t_hash where hiredate < to_date('2010-05-05','yyyy-mm-dd');

Execution Plan

----------------------------------------------------------

Plan hash value: 249093498

---------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

---------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 3 | 66 | 4 (0)| 00:00:01 | | |

| 1 | PARTITION HASH ALL| | 3 | 66 | 4 (0)| 00:00:01 | 1 | 2 |

|* 2 | TABLE ACCESS FULL| T_HASH | 3 | 66 | 4 (0)| 00:00:01 | 1 | 2 |

---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - filter("HIREDATE"<TO_DATE(' 2010-05-05 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

Note

-----

- dynamic sampling used for this statement (level=2)

SQL> select * from t_hash where hiredate = to_date('2010-05-05','yyyy-mm-dd');

Execution Plan

----------------------------------------------------------

Plan hash value: 616068738

------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

------------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 22 | 3 (0)| 00:00:01 | | |

| 1 | PARTITION HASH SINGLE| | 1 | 22 | 3 (0)| 00:00:01 | 2 | 2 |

|* 2 | TABLE ACCESS FULL | T_HASH | 1 | 22 | 3 (0)| 00:00:01 | 2 | 2 |

------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - filter("HIREDATE"=TO_DATE(' 2010-05-05 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

------------------

list

LIST方式分区

create table list_t

partition by LIST(DEPTNO)

( PARTITION D10_20 VALUES ('10','20') TABLESPACE users,

PARTITION D30 VALUES ('30') TABLESPACE users,

PARTITION D00 VALUES (DEFAULT) TABLESPACE USERS)

AS SELECT * FROM EMP;

SELECT * FROM EMP3 PARTITION (D10);

SELECT * FROM EMP3 PARTITION (D20);

SELECT * FROM EMP3 PARTITION (D00);

----------------------------------------------------

组合分区

对应分区还可以进行分区在分区,也就是子分区。 子分区一般是用于大规模数据的。

create table comp

(range_key date,

hash_key int,

data date)

partition by range(range_key)

subpartition by hash(hash_key) subpartitions 2

(

partition p1 values less than(to_date('2014-04-01','yyyy-mm-dd'))

(subpartition h1,

subpartition h2

),

partition p2 values less than(to_date('2015-04-01','yyyy-mm-dd'))

(subpartition h11,

subpartition h22

)

)

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