一、什么是分區表
表分區有以下優點:
1、數據查詢:數據被存儲到多個文件上,減少了I/O負載,查詢速度提高。
2、數據修剪:保存歷史數據非常的理想。
3、備份:將大表的數據分成多個文件,方便備份和恢復。
4、並行性:可以同時向表中進行DML操作,並行性性能提高,均衡I/O:可以把不同的分區映射到磁盤以平衡I/O,改善整個系統性能。
5、增強可用性:如果表的某個分區出現故障,表在其他分區的數據仍然可用;
6、維護方便:如果表的某個分區出現故障,需要修復數據,只修復該分區即可;
7、改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索速度。
8、需要注意的是包含LONG、LONGRAW數據類型的表不能分區,如果表格大於2G需要考慮分區。
二、分區表的種類
1、RANGE 范圍分區
說明:針對記錄字段的值在某個范圍。
規則:
(1)、每一個分區都必須有一個VALUES LESS THEN子句,它指定了一個不包括在該分區中的上限值。
分區鍵的任何值等於或者大於這個上限值的記錄都會被加入到下一個高一些的分區中。
(2)、所有分區,除了第一個,都會有一個隱式的下限值,這個值就是此分區的前一個分區的上限值。
(3)、在最高的分區中,MAXVALUE被定義。MAXVALUE代表了一個不確定的值。這個值高於其它分區中的任何分區鍵的值,
也可以理解為高於任何分區中指定的VALUE LESS THEN的值,同時包括空值。若不添加maxvalue的分區插入數值一旦超過設置的最大上限會報錯。
例一,按date范圍創建分區表
CREATE TABLE PART_TAB_CUSTOMER_BY_RANGE ( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, FIRST_NAME VARCHAR2(30) NOT NULL, LAST_NAME VARCHAR2(30) NOT NULL, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10), STATUS VARCHAR2(10), INSERT_DATE DATE ) PARTITION BY RANGE (INSERT_DATE) --按時間分區 ( PARTITION DATE_RANGE1 VALUES LESS THAN (TO_DATE(' 2001-01-01', 'YYYY-MM-DD')) TABLESPACE part_Data1, PARTITION DATE_RANGE2 VALUES LESS THAN (TO_DATE(' 2007-01-01', 'YYYY-MM-DD')) TABLESPACE part_Data2, PARTITION DATE_RANGE3 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3 )
例二、按照number范圍分區
PARTITION BY RANGE (CUSTOMER_ID) --按id分區
( PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE part_Data1, PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE part_Data2, PARTITION CUS_PART2 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3 )
2、LIST 列表分區
說明:該分區的特點是某列的值只有有限個值,基於這樣的特點我們可以采用列表分區。
規則:默認分區為DEFAULT,若不添加DEFAULT的分區插入數值不屬於所設置的分區會報錯。
例一、姓氏
CREATE TABLE PART_TAB_CUSTOMER_BY_LIST ( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10), CORP_ID VARCHAR2(3), INSERT_DATE DATE, SUM_DATE varchar2(4) ) PARTITION BY LIST (SEX) ( PARTITION MALE VALUES ('男') TABLESPACE part_Data1, PARTITION FEMALE VALUES ('女') TABLESPACE part_Data2 )
例二、varchar2的日期
PARTITION BY LIST (SUM_DATE) ( PARTITION SUM_DATE1 VALUES ('2012') TABLESPACE part_Data1, PARTITION SUM_DATE2 VALUES ('2013') TABLESPACE part_Data2, PARTITION SUM_DATE2 VALUES (DEFAULT) TABLESPACE part_Data2 )
3、HASH 散列分區
說明:這類分區是在列值上使用散列算法,以確定將行放入哪個分區中。
規則:當列的值沒有合適的條件,沒有范圍的規律,也沒有固定的值,建議使用散列分區。
散列分區為通過指定分區編號來均勻分布數據的一種分區類型,因為通過在I/O設備上進行散列分區,
使得這些分區大小一致。建議分區的數量采用2的n次方,這樣可以使得各個分區間數據分布更加均勻。
創建hash分區有兩種方法:一種方法是指定分區的名字,另一種方法是指定分區數量。
例一、常規方法指定分區名字
CREATE TABLE PART_TAB_CUSTOMER_BY_HASH ( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, FIRST_NAME VARCHAR2(30) NOT NULL, LAST_NAME VARCHAR2(30) NOT NULL, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10), STATUS VARCHAR2(10), INSERT_DATE DATE ) PARTITION BY HASH (CUSTOMER_ID) --按id散列 ( PARTITION hash1 TABLESPACE part_Data1, PARTITION hash2 TABLESPACE part_Data2 )
例二、指定分區數量
PARTITION BY HASH (empno) PARTITIONS 2 STORE IN (part_Data1,part_Data2);
--往往我們不需要知道bash分區的名字,因為數據放在哪個分區是oracle根據bash算法存放的,並不是用戶指定,
所以當用戶插入一條記錄,並不能確定放在哪個分區,這個不同於range和list
3、復合分區
說明:顧名思義,復合分區就由range+list+hash兩兩組合而來,一般分為range+list,list+range,range+hash,list+bash,這里指列出幾種常用組合。
規則:如果組合中存在hash,皆把hash分區作為子分區,原因大家可以通過hash分區的性質知道。
例一、range+list,這種分區是基於范圍分區和列表分區,表首先按某列進行范圍分區,然后再按某列進行列表分區。
CREATE TABLE PART_TAB_SALE_RANGE_LIST ( PRODUCT_ID VARCHAR2(5), SALES_DATE DATE, SALES_COST NUMBER(10), STATUS VARCHAR2(10), ) PARTITION BY RANGE(SALES_DATE) SUBPARTITION BY LIST (STATUS) ( PARTITION P1 VALUES LESS THAN (TO_DATE('2003-01-01','YYYY-MM-DD')) TABLESPACE part_Data1 ( SUBPARTITION P1SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1, SUBPARTITION P1SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2, SUBPARTITION P1SUB3 VALUES (DEFAULT) TABLESPACE part_Data3 ), PARTITION P2 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE part_Data2 ( SUBPARTITION P2SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1, SUBPARTITION P2SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2, SUBPARTITION P2SUB3 VALUES (DEFAULT) TABLESPACE part_Data3 ), PARTITION P3 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3 ( SUBPARTITION P3SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1, SUBPARTITION P3SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2, SUBPARTITION P3SUB3 VALUES (DEFAULT) TABLESPACE part_Data3 ) )
例二、range+bash,這種分區是基於范圍分區和散列分區,表首先按某列進行范圍分區,然后再按某列進行散列分區。
partition by range(transaction_date) subpartition by hash(transaction_id) subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03) (partition part_01 values less than(to_date(‘2006-01-01’,’yyyy-mm-dd’)), partition part_02 values less than(to_date(‘2010-01-01’,’yyyy-mm-dd’)), partition part_03 values less than(maxvalue) );
三、分區表的操作
1.DML操作
說明:DML操作和平常的表一樣,有異於的地方是增加了可以指定表的特定分區才執行DML操作。
例如,查詢分區表
SELECT * FROM PART_TAB_SALE_RANGE_LIST;--不指定分區直接查詢 SELECT * FROM PART_TAB_SALE_RANGE_LIST PARTITION(P2);--指定分區查詢 SELECT * FROM PART_TAB_SALE_RANGE_LIST SUBPARTITION(P1SUB2);--指定小分區查詢
對於分區表,指定分區執行DML效率更高,但,如果指定了分區,而條件中的數據又不在該分區中時,將不會產生任何DML操作。
2.DDL操作
1)添加分區
(1)對range分區表添加分區
ALTER TABLE PART_TAB_SALE_RANGE_LIST ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2009-06-01','YYYY-MM-DD'));
注意:增加一個分區的時候,增加的分區的條件必須大於現有分區的最大值,否則系統將提示ORA-14074 partition bound must collate higher than that of the last partition 錯誤。
(2)對range分區表list子分區添加分區
ALTER TABLE PART_TAB_SALE_RANGE_LIST MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');
2)刪除分區
(1)對range分區表刪除分區
ALTER TABLE PART_TAB_SALE_RANGE_LIST DROP PARTITION P3;
(2)對range分區表list子分區刪除子分區
ALTER TABLE PART_TAB_SALE_RANGE_LIST DROP SUBPARTITION P4SUB1;
注意:如果刪除的分區是表中唯一的分區,那么此分區將不能被刪除,要想刪除此分區,必須刪除表。
3)截斷分區
說明:截斷某個分區是指清空某個分區中的數據,並不會刪除分區,也不會刪除其它分區中的數據。當表中即使只有一個分區時,也可以截斷該分區。
注意:如果截斷的分區表有約束,需要先關閉約束。alter table sales disable/enable constraint restraint_name,截斷分區會使全局索引無效,需要重建。
(1)清空分區:
ALTER TABLE SALES TRUNCATE PARTITION P2;--這種方式使全局分區索引無效
ALTER TABLE SALES TRUNCATE PARTITION P2 update indexes;--這種方式使全局分區索引有效UPDATE GLOBAL INDEXES
(2)清空子分區:
ALTER TABLE PART_TAB_SALE_RANGE_LIST TRUNCATE SUBPARTITION P2SUB2;
ALTER TABLE PART_TAB_SALE_RANGE_LIST TRUNCATE SUBPARTITION P2SUB2 update indexes;
4)合並分區
說明:合並分區是將相鄰的分區合並成一個分區,結果分區將采用較高分區的界限,值得注意的是,不能將分區合並到界限較低的分區。
ALTER TABLE PART_TAB_SALE_RANGE_LIST MERGE PARTITIONS P1,P2 INTO PARTITION P2;
注意:在本例中將原有的表的part_01分區和part_02分區進行了合並,合並后的分區為part_02,
如果在合並的時候把合並后的分區定為part_01的時候,系統將提示ORA-14275 cannot reuse lower-bound partition as resulting partition 錯誤。
5)拆分分區
說明:拆分分區將一個分區拆分兩個新分區,拆分后原來分區不再存在。注意不能對HASH類型的分區進行拆分。
ALTER TABLE PART_TAB_SALE_RANGE_LIST SBLIT PARTITION P2 AT(TO_DATE('2003-03-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);
6)接合分區
說明:接合分區是將散列分區中的數據接合到其它分區中,當散列分區中的數據比較大時,可以增加散列分區,然后進行接合,
值得注意的是,接合分區只能用於散列分區中。
ALTER TABLE PART_TAB_SALE_RANGE_LIST COALESCA PARTITION;
7)重命名表分區
ALTER TABLE SALES RENAME PARTITION P21 TO P2;
8)移動分區
說明:把分區移動到令一個表空間,移動后要重建索引
alter table sales move partiton sp1 tablespace tablespace_name;
alter index index_name rebuild;
--查詢是否移動成功 SELECT TABLE_OWNER,TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,SUBPARTITION_COUNT FROM DBA_TAB_PARTITIONS WHERE TABLE_OWNER='SCOTT';
四、表分區相關的數據字典表
--顯示表分區信息 顯示數據庫所有分區表的詳細分區信息: select * from DBA_TAB_PARTITIONS
--顯示子分區信息 顯示數據庫所有組合分區表的子分區信息: select * from DBA_TAB_SUBPARTITIONS
--顯示數據庫所有分區表的信息: select * from DBA_PART_TABLES
--顯示數據庫可訪問的所有分區表的分區列信息:select * from DBA_PART_KEY_COLUMNS
DBA_IND_PARTITIONS
DBA_IND_SUBPARTITIONS
--查詢索引信息
select object_name,object_type,tablespace_name,sum(value)
from v$segment_statistics
where statistic_name IN ('physical reads','physical write','logical reads') and object_type='INDEX'
group by object_name,object_type,tablespace_name
order by 4 desc
五、局部索引與全局索引
表可以按range,hash,list分區,表分區后,其上的索引和普通表上的索引有所不同,oracle對於分區表上的索引分為2類,即局部索引和全局索引。
關於由Oracle分區表引出的局部索引與全局索引,我們將在“Oracle 索引”中做詳細講述