ORACLE的分区(Partitioning Option)是一种处理超大型表的技术。分区是一种“分而治之”的技术,通过将大表和索引分成可以管理的小块,从而避免了对每个表作为一个大的、单独的对象进行管理,为大量数据提供了可伸缩的性能。分区通过将操作分配给更小的存储单元,减少了需要进行管理操作的时间,并通过增强的并行处理提高了性能,通过屏蔽故障数据的分区,还增加了可用性。
分区对应用是透明的,可以通过标准的SQL语句对分区表进行操作。Oracle 的优化器在访问数据时会分析数据的分区情况,在进行查询时,那些不包含任何查询数据的分区将被忽略,从而大大提高系统的性能。
分区原则

1
.表分区的指南

a、表的大小
对于大表进行分区,将有益于大表操作的性能和大表的数据维护。通常当表的大小超过1.5GB-2GB,或对于OLTP系统,表的记录超过1000万,都应考虑对表进行分区。

b、数据访问特性
基于表的大部分查询应用,只访问表中少量的数据。对于这样表进行分区,可充分利用分区排除无关数据查询的特性。

c、数据维护
某些表的数据维护,经常按时间段删除成批的数据,例如按月删除历史数据。对于这样的表需要考虑进行分区,以满足维护的需要。因为删除(Delete)大量的数据,对系统开销很大,有时甚至是不可接受的。

d、只读数据
如果一个表中大部分数据都是只读数据,通过对表进行分区,可将只读数据存储在只读表空间中,对于数据库的备份是非常有益的。

e、并行数据操作(Parallel DML)
对于经常执行并行操作(如Parallel Insert,Parallel Update等)的表应考虑进行分区。

f、表的可用性
当对表的部分数据可用性要求很高时,应考虑进行表分区。


2
.选择分区字段(Partition Key)

当确定分区字段时,有两个主要因素特别需要考虑:

a、增强表的管理和维护性
通过Partition Key,可以使数据维护基于某个分区进行,如Drop或Truncate一个或多个分区。通过Paratition Key可控制只读的数据存储在相应的分区中,且这些分区存储在只读的表空间里,这将提高数据备份的性能。这类Partition Key通常与时间相关。
b、提高访问表的性能
通过Partition Key,可使查询的数据定位在一个或少量的分区中;这需要考虑最常用的查询条件。注意在考虑提高查询效率这个因素的同时,还应兼顾数据维护管理的因素,尽可能地避免相互间地冲突。
Oracle中提供了对表进行分区的机制,通过表分区,可以将表空间中数据按照某种方式分别存放到特定的分区中。表分区的作用:平衡IO操作,分区均匀,提高效率。
Oracle中表分区方法有:范围分区法、散列分区法、复合分区法、列表分区法。
范围分区:语法 Partition by range(); 适合数值型或日期型
示例:
1
create
table
Student
2
(
3
Studentid
integer
not
null
,
4
Studentname
varchar2
(
20
),
5
Score
integer
6
)
7
Partition
by
range(Score)
8
(
9
Partition p1
values
less than(
60
),
10
Partition p2
values
less than(
75
),
11
Partition p3
values
less than(
85
),
12
Partition p4
values
less than(maxvalue)
13 )
;
散列分区法:根据Oracle内部散列算法存储,语法 Partition by hash();
实例:
1
create
table
department
2
(
3
Deptno
int
,
4
Deptname
varchar2
(
24
)
5
)
6
Partition
by
hash(deptno)
7
(
8
Partition p1,
9
Partition p2
10
);
复合分区法:由上面两种方法复合而成
示例:
1
create
table
salgrade
2
(
3
grade
number
,
4
losal
number
,
5
hisal
number
6
)
7
Partition
by
range(grade)
8
Subpartition
by
hash(losal,hisal)
9
(
10
Partition p1
values
less than(
10
),
11
(subpartition sp1,subpartition sp2),
12
Partition p2
values
less than(
20
),
13
(subpartition sp3,subpartition sp4)
14
)
列表分区法:适合字符型 语法Partition by list()
实例:
1
create
table
customer
2
(
3
custNo
int
,
4
custname
varchar
(
20
),
5
custState
varchar
(
20
)
6
)
7
Partition
by
list(custState)
8
(
9
Partition saia
values
(
'
中国
'
,
'
韩国
'
,
'
日本
'
),
10
Partition Europe
values
(
'
英国
'
,
'
俄国
'
,
'
法国
'
),
11
Partition ameria
values
(
'
美国
'
,
'
加拿大
'
,
'
墨西哥
'
),
12
);
13
表分区维护:
添加分区:alter table student add partition p5 values less than(120);
删除分区:alter table student drop partition p4;
截断分区:alter table student truncate partition p5;
合并分区:alter table student merge partitions p3,p4 into partition p6;
分区的应用举例:
1
、分区表的建立:
某公司的每年产生巨大的销售记录,DBA向公司建议每季度的数据放在一个分区内,以下示范的是该公司1999年的数据(假设每月产生30M的数据),操作如下:
STEP1、建立表的各个分区的表空间:
CREATE TABLESPACE ts_sale1999q1
DATAFILE ‘
/
u1
/
oradata
/
sales
/
sales1999_q1.dat’
SIZE 100M
DEFAULT STORAGE (INITIAL 30m NEXT 30m MINEXTENTS
3
PCTINCREASE
0
)
CREATE TABLESPACE ts_sale1999q2
DATAFILE ‘
/
u1
/
oradata
/
sales
/
sales1999_q2.dat’
SIZE 100M
DEFAULT STORAGE (INITIAL 30m NEXT 30m MINEXTENTS
3
PCTINCREASE
0
)
CREATE TABLESPACE ts_sale1999q3
DATAFILE ‘
/
u1
/
oradata
/
sales
/
sales1999_q3.dat’
SIZE 100M
DEFAULT STORAGE (INITIAL 30m NEXT 30m MINEXTENTS
3
PCTINCREASE
0
)
CREATE TABLESPACE ts_sale1999q4
DATAFILE ‘
/
u1
/
oradata
/
sales
/
sales1999_q4.dat’
SIZE 100M
DEFAULT STORAGE (INITIAL 30m NEXT 30m MINEXTENTS
3
PCTINCREASE
0
)
STEP2、建立基于分区的表:
CREATE TABLE sales
(invoice_no NUMBER,
...
sale_date DATE NOT NULL )
PARTITION BY RANGE (sale_date)
(PARTITION sales1999_q1
VALUES LESS THAN (TO_DATE(‘
1999
-
04
-
01
’,’YYYY
-
MM
-
DD’)
TABLESPACE ts_sale1999q1,
PARTITION sales1999_q2
VALUES LESS THAN (TO_DATE(‘
1999
-
07
-
01
’,’YYYY
-
MM
-
DD’)
TABLESPACE ts_sale1999q2,
PARTITION sales1999_q3
VALUES LESS THAN (TO_DATE(‘
1999
-
10
-
01
’,’YYYY
-
MM
-
DD’)
TABLESPACE ts_sale1999q3,
PARTITION sales1999_q4
VALUES LESS THAN (TO_DATE(‘
2000
-
01
-
01
’,’YYYY
-
MM
-
DD’)
TABLESPACE ts_sale1999q4 );
2
、分区表的扩容:
到了1999年年底,DBA应向表中加入2000年的表空间,同样是每季度一个表空间,由于公司业务欣欣向荣,预计每个分区为40M,操作如下。
STEP1、建立表空间:
CREATE TABLESPACE ts_sale2000q1
DATAFILE ‘
/
u1
/
oradata
/
sales
/
sales2000_q1.dat’
SIZE 130M
DEFAULT STORAGE (INITIAL 40m NEXT 40m MINEXTENTS
3
PCTINCREASE
0
)
其他表空间ts_sale2000q2,ts_sale2000q3,ts_sales2000q4如法炮制。
STEP2、为表添加表空间:
ALTER TABLE sales
ADD PARTITION sales2000_q1
VALUES LESS THAN (TO_DATE(‘
2000
-
04
-
01
’,’YYYY
-
MM
-
DD’)
TABLESPACE ts_sale2000q1;
其他分区sales2000_q1,sales2000_q1,sales2000_q1如法炮制。
3
、删除不必要的分区:
公司规定:销售的明细数据两年内必须保存在线。到2001年,DBA必须将1999年的数据备份(备份方法见5、EXPORT分区),将1999年的分区删除,将空间供后来的数据使用。如此循环,永远保持两年的销售数据在线。
STEP1、DROP 分区:
ALTER TABLE sales
DROP PARTION sales1999_q1;
ALTER TABLE sales
DROP PARTION sales1999_q2;
ALTER TABLE sales
DROP PARTION sales1999_q3;
ALTER TABLE sales
DROP PARTION sales1999_q4;
STEP2、利用操作系统的工具删除以上表空间占用的文件(表空间基于裸设备无须次步),UNIX系统为例:
oracle$ rm
/
u1
/
oradata
/
sales
/
sales1999_q1.dat
oracle$ rm
/
u1
/
oradata
/
sales
/
sales1999_q2.dat
oracle$ rm
/
u1
/
oradata
/
sales
/
sales1999_q3.dat
oracle$ rm
/
u1
/
oradata
/
sales
/
sales1999_q4.dat
4
、分区的其他操作:
分区的其他操作包括截短分区(truncate),将存在的分区划分为多个分区(split),交换分区(exchange),重命名(rename),为分区建立索引等。DBA可以根据适当的情况使用。
以下仅说明分裂分区(split),例如该公司1999年第四季度销售明细数据急剧增加(因为庆国庆、迎千禧、贺回归),DBA向公司建议将第四季度的分区划分为两个分区,每个分区放两个月份的数据,操作如下:
STEP1、按(
1
)的方法建立两个分区的表空间ts_sales1999q4p1,
ts_sales1999q4p2;
STEP2、给表添加两个分区sales1999_q4_p1,sales1999_q4_p2;
STEP3、分裂分区:
ALTER TABLE sales
SPLIT PARTITON sales1999_q4
AT TO_DATE (‘
1999
-
11
-
01
’,’YYYY
-
MM
-
DD’)
INTO (partition sales1999_q4_p1, partition sales1999_q4_p2)
5
、查看分区信息:
DBA要查看表的分区信息,可查看数据字典USER_EXTENTS,操作如下:
SVRMGRL
>
SELECT
*
FROM user_extents WHERE SEGMENT_NAME
=
’SALES’;
SEGMENT_NA PARTITION_ SEGMENT_TYPE TABLESPACE
----------
------------
---------------
--------------
SALES SALES1999_Q1 TABLE PARTITION TS_SALES1999Q1
SALES SALES1999_Q2 TABLE PARTITION TS_SALES1999Q2
SALES SALES1999_Q3 TABLE PARTITION TS_SALES1999Q3
SALES SALES1999_Q4 TABLE PARTITION TS_SALES1999Q4
SALES SALES2000_Q1 TABLE PARTITION TS_SALES1999Q1
SALES SALES2000_Q2 TABLE PARTITION TS_SALES1999Q2
SALES SALES2000_Q3 TABLE PARTITION TS_SALES1999Q3
SALES SALES2000_Q4 TABLE PARTITION TS_SALES1999Q4
5
、EXPORT分区:
ORACLE8的EXPORT 工具可在表的分区以及导出数据,例如到2001年,DBA必须将1999年的数据按分区导出,操作如下:
oracle$ exp sales
/
sales_password tables
=
sales:sales1999_q1 rows
=
Y
file
=
sales1999_q1.dmp
oracle$ exp sales
/
sales_password tables
=
sales:sales1999_q2 rows
=
Y
file
=
sales1999_q2.dmp
oracle$ exp sales
/
sales_password tables
=
sales:sales1999_q3 rows
=
Y
file
=
sales1999_q3.dmp
oracle$ exp sales
/
sales_password tables
=
sales:sales1999_q4 rows
=
Y
file
=
sales1999_q4.dmp
6
、IMPORT分区:
ORACLE8的IMPORT 工具可在表的分区以及导入数据,例如在2001年,用户要查看1999年的数据,DBA必须导入1999年的数据,使之在线,操作如下:
STEP1、建立表的1999年的四个表空间和相应的分区,参照(
2
);
STEP2、导入数据:
oracle$ imp sales
/
sales_password FILE
=
sales1999_q1.dmp
TABLES
=
(sales:sales1999_q1) IGNORE
=
y
oracle$ imp sales
/
sales_password FILE
=
sales1999_q2.dmp
TABLES
=
(sales:sales1999_q2) IGNORE
=
y
oracle$ imp sales
/
sales_password FILE
=
sales1999_q3.dmp
TABLES
=
(sales:sales1999_q3) IGNORE
=
y
oracle$ imp sales
/
sales_password FILE
=
sales1999_q4.dmp
TABLES
=