Oracle笔记九:分区PARTITION
- 1、简介
- 1.1、概念
- 1.2、作用
- 1.3、运用范围
- 1.4、优缺点
- 2、表分区类型
- 2.1、范围分区
- 2.2、列表分区
- 2.3、散列分区
- 2.4、组合范围散列分区
- 4.5、复合范围散列分区
- 3、分区维护
- 3.1、增加分区
- 3.2、合并分区
- 3.2.1、coalesce partition
- 3.2.2、merge partitions
- 3.3、删除分区
- 3.4、交换分区
- 3.5、修改LIST分区
- 3.5.1、ADD VALUES
- 3.5.2、DROP VALUES
- 3.6、拆分分区
- 3.7、截断分区
- 3.8、移动分区
- 3.9、重命名分区
- 3.10、修改分区默认属性
- 3.11、修改子分区模板属性
1、简介
1.1、概念
分区表:
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
1.2、作用
Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。
分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。每个分区有自己的名称,还可以选择自己的存储特性。从数据库管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,这就使数据库管理员在管理分区后的对象时有相当大的灵活性。但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用SQL DML 命令访问分区后的表时,无需任何修改。
1.3、运用范围
1、表的大小超过2GB。
2、表中包含历史数据,新的数据被增加都新的分区中。
1.4、优缺点
优点:
1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
缺点:
分区表相关:已经存在的表没有方法可以直接转化为分区表。不过Oracle 提供了在线重定义表的功能。
2、表分区类型
2.1、范围分区
范围分区将数据基于范围映射到每一个分区,这个范围是你在创建分区时指定的分区键决定的。这种分区方式是最为常用的,并且分区键经常采用日期。
create table tabName (...) PARTITION BY RANGE (colName)
(
PARTITION partName1 VALUES LESS THEN (100000) TABLESPACE tbsName1,
PARTITION partName2 VALUES LESS THEN (200000) TABLESPACE tbsName2
)
当使用范围分区时,请考虑以下几个规则:
1、每一个分区都必须有一个VALUES LESS THEN子句,它指定了一个不包括在该分区中的上限值。分区键的任何值等于或者大于这个上限值的记录都会被加入到下一个高一些的分区中。
2、所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。
3、在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。这个值高于其它分区中的任何分区键的值,也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。
2.2、列表分区
该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。
create table tabName (...) PARTITION BY LIST (colName)
(
PARTITION partName1 VALUES (100000) TABLESPACE tbsName1,
PARTITION partName2 VALUES (200000) TABLESPACE tbsName2
)
2.3、散列分区
这类分区是在列值上使用散列算法,以确定将行放入哪个分区中。当列的值没有合适的条件时,建议使用散列分区。
散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区,使得这些分区大小一致。
create table tabName (...) PARTITION BY HASH (colName)
(
PARTITION partName1 TABLESPACE tbsName1,
PARTITION partName2 TABLESPACE tbsName2
);
--可简写如下:
create table tabName (...) PARTITION BY HASH (colName) PARTITIONS 2
store in ( tbsName1,tbsName2 );
hash分区最主要的机制是根据hash算法来计算具体某条纪录应该插入到哪个分区中,hash算法中最重要的是hash函数,Oracle中如果你要使用hash分区,只需指定分区的数量即可。建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。
2.4、组合范围散列分区
这种分区是基于范围分区和列表分区,表首先按某列进行范围分区,然后再按某列进行列表分区,分区之中的分区被称为子分区。
create table tabName (...) PARTITION BY RANGE (colName1) SUBPARTITION BY LIST (colName2)
(
PARTITION P1 VALUES LESS THEN(TO_DATE('2003-01-01','YYYY-MM-DD'))TABLESPACE tbsName1
(
SUBPARTITION P1subpartName1 VALUES (100000) TABLESPACE tbsName1,
SUBPARTITION P1subpartName2 VALUES (200000) TABLESPACE tbsName2
),
PARTITION P2 VALUES LESS THEN(TO_DATE('2003-04-01','YYYY-MM-DD'))TABLESPACE tbsName1
(
SUBPARTITION P2subpartName1 VALUES (100000) TABLESPACE tbsName1,
SUBPARTITION P2subpartName2 VALUES (200000) TABLESPACE tbsName2
)
);
4.5、复合范围散列分区
这种分区是基于范围分区和散列分区,表首先按某列进行范围分区,然后再按某列进行散列分区。
create table tabName (...) partition by range(colName1)subpartition by hash(colName2) subpartitions 3 store in (tbsName1,tbsName2,tbsName3)
(
PARTITION P1 VALUES LESS THEN(TO_DATE('2003-01-01','YYYY-MM-DD'))TABLESPACE tbsName1,
PARTITION P2 VALUES LESS THEN(TO_DATE('2003-04-01','YYYY-MM-DD'))TABLESPACE tbsName1,
partition P3 values less THEN(maxvalue)
);
3、分区维护
分区表的管理笔记(仅限于对普通表,即堆表的分区管理,IOT跟CLUSTER TABLE不再讨论范围内)
3.1、增加分区
语法是:alter table xxx add partition…
需要注意的是如果分区中存在maxvalue或default分区add partition会报错,应使用split
如:
Alter table t_range add partition p5 values less than (50) [tablespace users];
--50 要大于之前分区的所有值
Alter table t_list add partition p5 values (7,8,9) [tablespace users];
--7,8,9均不能在之前分区中出现
Alter table t_hash add partition [p5] [tablespace users];
增加子分区:
Alter table xxx modify partition p1 add subpartition …
如:
增加RANGE-HASH子分区
ALTER TABLE diving MODIFY PARTITION locations_us
ADD SUBPARTITION us_locs5 TABLESPACE us1;
Range、list增加分区不会影响索引(包括global与local),HASH增加分区会让数据重新分配,产生IO,如果不指定update indexes 选项则会导致有数据移动的索引unusable,需要重新编译。
当然,我们说的对索引的影响都是在表中有数据的情况下,没数据当然影响不到索引了。
3.2、合并分区
3.2.1、coalesce partition
Alter table xxx coalesce partion [update indexes];
Alter table xxx modify partition p1 coalesce subpartition;
仅适用于HASH分区或子分区,合并一次会减少一个分区(最少能减少到1个),数据重新分配,产生IO,有数据移动的索引失效(如果不指定update indexes的话).
3.2.2、merge partitions
Alter table xxx merge partitions/subpartitions p1,p2 into partiton/subpartition p3 [TABLESPACE tablespace_name];
HASH不适用;表分区必须是相邻的。
跟COALESCE一样,会产生IO,数据量大的话,IO也是相当大的。同样可以用UPDATE INDEXES 避免索引失效
3.3、删除分区
Alter table xxx drop partition ppp;
删除子分区:
Alter table xxx drop subpartition ppp;
此功能hash不支持。同时要注意,删除分区会同时删除该分区内数据。
同样,如果不指定update indexes的话该操作会导致GLOBAL索引失效,而LOCAL不会,因为对应的LOCAL索引分区也被删除了嘛,其他分区的LOCAL不会受到影响。
3.4、交换分区
Alter table tb1 exchange partition/subpartition p1 with table tb2;
据说是采用了更改数据字典的方式,所以速度比较快。
可以是分区跟非分区表交换,子分区跟非分区表交换,组合分区跟分区表交换。
例如:
组合分区跟分区表交换:
CREATE TABLE t1 (i NUMBER, j NUMBER)
PARTITION BY HASH(i)
(PARTITION p1, PARTITION p2);
CREATE TABLE t2 (i NUMBER, j NUMBER)
PARTITION BY RANGE(j)
SUBPARTITION BY HASH(i)
(PARTITION p1 VALUES LESS THAN (10)
SUBPARTITION t2_pls1
SUBPARTITION t2_pls2,
PARTITION p2 VALUES LESS THAN (20)
SUBPARTITION t2_p2s1
SUBPARTITION t2_p2s2));
ALTER TABLE t2 EXCHANGE PARTITION p1 WITH TABLE t1 WITH VALIDATION; |
3.5、修改LIST分区
3.5.1、ADD VALUES
Alter table xxx modify partition/subpartition p1 add values(7,9);
要注意的是,增加的VALUES不能在其他分区列的VALUES值中存在,也不能在DEFAULT分区(如果有的话)中有相应VALUES.
不会影响索引
3.5.2、DROP VALUES
Alter table xxx modify partition/subpartition p1 drop values(8,9);
同样,删除的values 不能存在记录.
不会影响索引
3.6、拆分分区
功能与MERGE PARTITIONS相反。通常我们会用来拆分MAXVALUE/DEFAULT分区。
Range partition:
Alter table xxx split partition/subpartition p1 at (15) into (partition/subpartition p1_new1,partition/subpartition p1_new2);
List partition:
Alter table xxx split partition/subpartition p1 values(15,16) into (partition/subpartition p1_new1,partition/subpartition p1_new2);
原分区中符合新值定义的记录会存入第一个分区,其他存入第二个分区,当然,在新分区后面可以指定属性,比如TABLESPACE。
HASH分区不适用。
会产生IO,同样,可用update indexes 来避免索引失效
3.7、截断分区
跟TRUNCATE TABLE一样,截断该分区内的数据。
Alter table xxx truncate partition/subpartition p1;
同样,可用update indexes 来避免索引失效
使用场景如下:
由于客户某表月初通过ogg导入数据较多,ogg未能完成。因此决定使用数据泵临时导入。
停止ogg,删除表分区数据。通过delete加条件筛选数据,发现数据量较大,尝试删除,运行很长时间后,undo不够用报错。
决定,truancate该分区。查看表的分区,发现存在数个全局索引和本地索引,百度一下对分区表某分区进行drop/truncate操作。
操作内容:
① 马上回收空间:
alter table table_name truncate partition partition_name drop storage;
② 同时维护全局索引:
alter table table_name drop partition partition_name update global indexes;
㈡ 对全局索引的作用
大分区表truncate partition后,需要对全局索引进行维护,否则,global index会变成unusable
问题介绍:
① 在drop partition时,为了维护global索引,要加update indexes或是update global indexes条件
②在truncate partition时也要维护global索引,要加update indexes或是update global indexes条件
UPDATE INDEXES同时维护全局和本地索引
对于DROP/TRUNCATE PARTITION而言 ,二者没有太大的区别
对于MERGE和SPLIT PARTITION,你就可以看到二者的区别了
虽然index是变得valid了,但是index的空间没有释放
因为该操作不等于REBUILD,只是在进行DDL的时候,同步维护索引信息而已
综上,可以使用
alter table table_name truncate partition (p1) update indexes;
或
alter table table_name truncate partition (p1) update global indexes;
3.8、移动分区
Alter table xxx move partition/subpartition p1 …;
有些功能比如改变分区表空间,modify partition就做不到,此时就可以用move partition来做。
示例如下:
ALTER TABLE parts MOVE PARTITION depot2
TABLESPACE ts094 NOLOGGING COMPRESS;
(如果指定compress,affects only future storage, but not existing data.)
同样,可用update indexes 来避免索引失效
3.9、重命名分区
Alter table xxx rename partition/subpartition p1 to p1_new;
3.10、修改分区默认属性
修改表属性:alter table xxx modify default attributes …
修改分区属性(适用于组合分区):alter table xxx modify default attributes for partition p1 …
只对以后添加的分区产生影响,适用于所有分区,其中hash分区只能修改表空间属性。
如:
Alter table xxx modify default attributes tablespace users;
3.11、修改子分区模板属性
Alter table xxx set subpartition template (…);
仅影响以后的子分区,当前的子分区属性不会改变
如:
Alter table xxx set subpartition template
(partition p1 tablespace tbs_1,
Partition p2 tablespace tbs_2);
如果要取消掉子分区模板:
Alter table xxx set subpartition template ();