1. 程式人生 > >Oracle 表分區(Partition)

Oracle 表分區(Partition)

分布 區分 重要 表分區 varchar i/o 多個 oracle reat

  表分區功能能夠改善應用程序性能,提高數據庫可管理性和可用性,是數據庫管理非常關鍵的技術。數據庫通過使用分區提高查詢性能,簡化日常管理維護工作。

  1 分區優點

  1) 減少維護工作量,獨立管理每個表分區比管理整個大表要輕松的多

  2) 增加數據庫的可用性,由於將數據分散到各個分區中,減少了數據損壞的可能性

  3) 均衡I/O,減少競爭,通過把表的不同分區分配到不同的磁盤來平衡I/O改善性能

  4) 分區對用戶保持透明,用戶感受不到它的存在

  5) 提高查詢速度,對於大表的DML操作可以分解到表的不同分區來執行,可以加快執行速度

  

  2 分區缺點

  已經存在的表,不能直接轉化為分區表

  3 什麽時候使用分區表

1) 表的大小超過2GB 2) 表中包含歷史數據,新的數據被增加到新的分區中 4 分區類型 1) Range 分區 2) HASH分區(散列分區) 3) 列表分區 4) 組合分區(復合分區) 1) Range Partition

Range分區是應用範圍比較廣的表分區方式,它是以列的值的範圍來做為分區的劃分條件,將記錄存放到列值所在的range分區中。

如按照時間劃分,2017年第一季度的數據放到第一分區,二季度的數據放到第二分區,在創建的時候,需要指定基於的列,以及分區的範圍值。在按時間分區時, 如果某些記錄暫無法預測範圍,可以創建 maxvalue 分區,所有不在指定範圍內的記錄都會被存儲到 maxvalue 所在分區中。

假設有一個emp表,表中有數據200000行,我們將此表通過hire_date進行分區,每個分區存儲50000行,我們將每個分區保存到單獨的表空間中,這樣數據文件就可以跨越多個物理磁盤。下面是創建表和分區的代碼,如下:

create table emp_range
(
empno number not null primary key,
deptno number not null,
first_name varchar2(30) not null,
last_name varchar2(30) not null,
status char(1),
hire_date date not null
)
partition by range(hire_date)
(
partition hire_part1 values less than(to_date(‘2017-04-01‘,‘yyyy-mm-dd‘)) tablespace emp_space01,
partition hire_part2 values less than(to_date(‘2017-07-01‘,‘yyyy-mm-dd‘)) tablespace emp_space02,
partition hire_part3 values less than(to_date(‘2017-10-01‘,‘yyyy-mm-dd‘)) tablespace emp_space03,
partition hire_part4 values less than(to_date(‘2018-01-01‘,‘yyyy-mm-dd‘)) tablespace emp_space04
);

測試數據

insert into emp_range(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 10,‘latiny1‘,‘liu‘,‘1‘, to_date(‘2017-01-02‘,‘yyyy-mm-dd‘));

insert into emp_range(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 20,‘latiny2‘,‘liu2‘,‘1‘, to_date(‘2017-04-02‘,‘yyyy-mm-dd‘));

insert into emp_range(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 30,‘latiny3‘,‘liu3‘,‘1‘, to_date(‘2017-07-02‘,‘yyyy-mm-dd‘));

insert into emp_range(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 40,‘latiny4‘,‘liu4‘,‘1‘, to_date(‘2017-10-02‘,‘yyyy-mm-dd‘));

按分區查詢結果

select *
from emp_range partition(hire_part1);

2) HASH分區

散列分區是在列值上使用散列算法,以確定將行放入哪個分區中。當列的值沒有合適的條件時,建議使用散列分區。散列分區為通過指定分區編號來均勻分布數據的一種分區類型,因為通過在I/O設備上進行散列分區,使得這些分區大小一致。

drop table emp_hash;
create table emp_hash
(
empno number not null primary key,
deptno number not null,
first_name varchar2(30) not null,
last_name varchar2(30) not null,
status char(1),
hire_date date not null
)
partition by hash(deptno)
(
partition dep_part1 tablespace emp_space01,
partition dep_part2 tablespace emp_space02,
partition dep_part3 tablespace emp_space03
);

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 10,‘latiny1‘,‘liu‘,‘1‘, to_date(‘2017-01-02‘,‘yyyy-mm-dd‘));

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 20,‘latiny2‘,‘liu2‘,‘1‘, to_date(‘2017-04-02‘,‘yyyy-mm-dd‘));

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 30,‘latiny3‘,‘liu3‘,‘1‘, to_date(‘2017-07-02‘,‘yyyy-mm-dd‘));

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 40,‘latiny4‘,‘liu4‘,‘1‘, to_date(‘2017-10-02‘,‘yyyy-mm-dd‘));

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 50,‘latiny5‘,‘liu5‘,‘1‘, to_date(‘2017-11-02‘,‘yyyy-mm-dd‘));

insert into emp_hash(empno, deptno, first_name, last_name, status, hire_date)
values (seq_par_id.nextval, 60,‘latiny6‘,‘liu6‘,‘1‘, to_date(‘2017-08-02‘,‘yyyy-mm-dd‘));

select *
from emp_hash partition(dep_part1);

散列分區最主要的機制是根據Hash算法來計算具體某條紀錄應該插入到哪個分區中, Hash算法中最重要的是Hash函數,Oracle中如果你要使用Hash分區,只需指定分區的數量即可。建議分區的數量采用2的n次方,這樣可以使得各個分區間數據分布更加均勻。

3) 列表分區 該分區的特點是某列的值只有幾個,基於這樣的特點我們可以采用列表分區。

create table emp
(
empno number not null primary key,
deptno number not null,
first_name varchar2(30) not null,
last_name varchar2(30) not null,
status char(1),
hire_date date not null
)
partition by list(status)
(
partition status_active values (‘active‘) tablespace emp_ls01,
partition status_inactive values (‘inactive‘) tablespace emp_ls02
)

4) 組合分區 範圍--散列分區 這種分區是基於範圍分區和散列分區,表首先按某列進行範圍分區,然後再按某列進行散列分區。

create table emp
(
empno number not null primary key,
deptno number not null,
first_name varchar2(30) not null,
last_name varchar2(30) not null,
status char(1),
hire_date date not null
)
partition by range(hire_date)subpartition by hash(deptno) subpartitions 4 store in (emp_space01,emp_space02,emp_space03,emp_space04)
(
partition part_01 values less than(to_date(‘2017-01-01‘,’yyyy-mm-dd’)),
partition part_02 values less than(to_date(‘2017-04-01‘,’yyyy-mm-dd’)),
partition part_03 values less than(to_date(‘2017-07-01‘,’yyyy-mm-dd’)),
partition part_04 values less than(to_date(‘2017-10-01‘,’yyyy-mm-dd’))
);

範圍--列表分區
這種分區是基於範圍分區和列表分區,表首先按某列進行範圍分區,然後再按某列進行列表分區,分區之中的分區被稱為子分區。

create table emp
(
empno number not null primary key,
deptno number not null,
first_name varchar2(30) not null,
last_name varchar2(30) not null,
status char(1),
hire_date date not null
)
partition by range(hire_date)subpartition by list(status)
(
partition part_01 values less than(to_date(‘2017-01-01‘,’yyyy-mm-dd’)) tablespace emp_space01
(
subpartition p1sub1 values (‘1‘) tablespace emp_space01,
subpartition p1sub2 values (‘0‘) tablespace emp_space01

),
partition part_02 values less than(to_date(‘2017-04-01‘,’yyyy-mm-dd’)) tablespace emp_space02
(
subpartition p2sub1 values (‘1‘) tablespace emp_space02,
subpartition p2sub2 values (‘0‘) tablespace emp_space02
)
);

Oracle 表分區(Partition)