隨着表中行數的增多,管理和性能性能影響也將隨之增加。備份將要花費更多時間,恢復也將 要花費更說的時間,對整個數據表的查詢也將花費更多時間。通過把一個表中的行分為幾個部分,可以減少大型表的管理和性能問題,以這種方式划分發表數據的方法稱為對表的分區。分區表的優勢:
(1)改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索速度;
(2)方便數據管理:因為分區表的數據存儲在多個部分中,所以按分區加載和刪除數據比在大表中加載和刪除數據更容易;
(3)方便備份恢復:因為分區比被分區的表要小,所以針對分區的備份和恢復方法要比備份和恢復整個表的方法多。
1)范圍分區
2)列表分區
3)散列分區(hash分區)
4)復合分區(子分區)
1,創建4個測試用的表空間,每個表空間作為一個獨立分區(考慮到Oracle中分區映射的實現方式,建議將表中的分區數設置為2的乘方,以便使數據均勻分布)
SYS>create tablespace partition1 datafile '/home/oracle/app/oradata/orcl/partition1.dbf' size 20m;
SYS>create tablespace partition2 datafile '/home/oracle/app/oradata/orcl/partition2.dbf' size 20m;
SYS>create tablespace partition3 datafile '/home/oracle/app/oradata/orcl/partition3.dbf' size 20m;
SYS>create tablespace partition4 datafile '/home/oracle/app/oradata/orcl/partition4.dbf' size 20m;
范圍分區就是對數據表中的某個值的范圍進行分區,根據某個值的范圍,決定將該數據存儲在哪個分區上。如根據序號分區,根據業務記錄的創建日期進行分區等(聯通每個月的賬單記錄就用的分區表存儲)。
需求描述:有一個物料交易表,表名:material_transactions。該表將來可能有千萬級的數據記錄數。要求在建該表的時候使用分區表。這時候我們可以使用序號分區三個區,每個區中預計存儲三千萬的數據,也可以使用日期分區,如每五年的數據存儲在一個分區上。
根據交易記錄的序號分區建表:----為了測試需要做以下修改:

交易號小於2的記錄存儲在分區1上,大於等於2且小於4的交易號儲存在分區2上,大於等於4且小於6的交易號儲存在分區3上,大於等於6的交易號存儲在分區4上。(不必為最后一個分區指定最大值,maxvalue關鍵字會告訴Oracle使用這個分區來存儲在前面幾個分區中不能儲存的數據)。
2.1,向分區表里面插入數據:

2.2,查詢表數據
不指定分區:

指定分區:

2.3,更改表數據

2.4,刪除表數據

3,散列分區(hash分區)
除范圍分區外,Oracle還支持散列分區。散列分區通過在分區鍵值上執行一個散列函數來說決定數據的物理位置。在范圍分區中,分區鍵的連續值通常儲存在相同的分區中。而在散列分區中,連續的分區鍵值不必儲存在相同的分區中。散列分區把記錄分布在比范圍分區更多的分區上,這減少了I/O爭用的可能性。

還有一種定義hash分區的方式是:partition by hash(column) partition n store in (tbs1,,,tbsm)。表空間的數目不必等於分區的數目,即n不一定等於m,如果指定的分區數目比表空間的數目多,則分區將會以循環的方式分配到表空間中,一個表空間可以含有多個分區:

4,列表分區
列表分區告訴Oracle所有可能的值,並指定應該插入相應行的分區,它適用於表的數據量很大但是某一列的值只有少量幾種。

在列表分區中,可以使用關鍵字default來指定未列出的所有情況。(上述4個分區創建在一個表空間中)
5,復合分區(子分區)
有時候我們需要根據范圍分區后,每個分區內的數據再散列地分布在幾個表空間中,這樣我們就要使用復合分區。復合分區是先使用范圍分區,然后在每個分區內再使用散列分區/列表分區的一種分區方法。如將物料交易的記錄按時間分區,然后每個分區中的數據分三個子分區,將數據散列地存儲在三個指定的表空間中:

p1:sales_cost小於1
p1sub1:sales_cost小於1,且status為ACTIVE
p1sub2:sales_cost小於1,且status為INACTIVE
p2:sales_cost大於等於1,小於3
p2sub1:sales_cost大於等於1,小於3,且status為ACTIVE
p2sub2:sales_cost大於等於1,小於3,且status為INACTIVE
操作測試:

補充:如果插入的值不在自定義的所有分區范圍內,將由Oracle來分配。
1、添加分區
以下代碼給SALES表添加了一個P3分區:
ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));
注意:以上添加的分區界限應該高於最后一個分區界限。
以下代碼給SALES表的P3分區添加了一個P3SUB1子分區
ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');
2、刪除分區
以下代碼刪除了P3表分區:
ALTER TABLE SALES DROP PARTITION P3;
在測試中遇到這樣的情況。如果表創建了分區,如果要刪除數據文件(表空間文件),則要先刪除分區,然后才能刪除數據文件(但是在刪除數據文件時,必須要保留一個分區才能最終刪除數據文件&表空間文件)。當然,也可以直接就刪除表也行,剛所有的全刪除,但是表空間文件還在。
在以下代碼刪除了P4SUB1子分區:
ALTER TABLE SALES DROP SUBPARTITION P4SUB1;
注意:如果刪除的分區是表中唯一的分區,那么此分區將不能被刪除,要想刪除此分區,必須先刪除表。
3、截斷分區
截斷某個分區是指刪除某個分區中的數據,並不會刪除分區,也不會刪除其它分區中的數據。當表中即使只有一個分區時,也可以截斷該分區。通過以下代碼截斷分區:
ALTER TABLE SALES TRUNCATE PARTITION P2;
通過以下代碼截斷子分區:
ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;
4、合並分區
合並分區是將相鄰的分區合並成一個分區,結果分區將采用較高分區的界限,值得注意的是,不能將分區合並到界限較低的分區。以下代碼實現了P1 P2分區的合並:
ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2;
5、拆分分區
拆分分區將一個分區拆分兩個新分區,拆分后原來分區不再存在。注意不能對HASH類型的分區進行拆分。
ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);
6、接合分區(coalesca)
結合分區是將散列分區中的數據接合到其它分區中,當散列分區中的數據比較大時,可以增加散列分區,然后進行接合,值得注意的是,接合分區只能用於散列分區中。通過以下代碼進行接合分區:
ALTER TABLE SALES COALESCA PARTITION;
7、重命名表分區
以下代碼將P21更改為P2
ALTER TABLE SALES RENAME PARTITION P21 TO P2;
8、跨分區查詢
select sum( *) from (
select count(*) cn from t_table_SS PARTITION (P200709_1)
union all
select count(*) cn from t_table_SS PARTITION (P200709_2)
);
9、與分區相關的表和視圖:
分區 |
--查詢表上有多少分區:SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='tableName'
--顯示表分區信息 顯示數據庫所有分區表的詳細分區信息:select * from DBA_TAB_PARTITIONS
--顯示當前用戶可訪問的所有分區表的詳細分區信息:select * from ALL_TAB_PARTITIONS
--顯示當前用戶所有分區表的詳細分區信息:select * from USER_TAB_PARTITIONS
|
子分區 |
--顯示子分區信息 顯示數據庫所有組合分區表的子分區信息:select * from DBA_TAB_SUBPARTITIONS
--顯示當前用戶可訪問的所有組合分區表的子分區信息:select * from ALL_TAB_SUBPARTITIONS
--顯示當前用戶所有組合分區表的子分區信息:select * from USER_TAB_SUBPARTITIONS
|
分區表 |
--顯示數據庫所有分區表的信息:select * from DBA_PART_TABLES where table_name=upper('dinya_test')
--顯示當前用戶可訪問的所有分區表信息:select * from ALL_PART_TABLES
--顯示當前用戶所有分區表的信息:select * from USER_PART_TABLES
|
分區列 |
--顯示分區列 顯示數據庫所有分區表的分區列信息:select * from DBA_PART_KEY_COLUMNS
--顯示當前用戶可訪問的所有分區表的分區列信息:select * from ALL_PART_KEY_COLUMNS
--顯示當前用戶所有分區表的分區列信息:select * from USER_PART_KEY_COLUMNS
|
子分區列 |
--顯示子分區列 顯示數據庫所有分區表的子分區列信息:select * from DBA_SUBPART_KEY_COLUMNS
--顯示當前用戶可訪問的所有分區表的子分區列信息:select * from ALL_SUBPART_KEY_COLUMNS
--顯示當前用戶所有分區表的子分區列信息:select * from USER_SUBPART_KEY_COLUMNS
|
特例 | --怎樣查詢出oracle數據庫中所有的的分區表:select * from user_tables a where a.partitioned='YES' |
--刪除一個表的數據是
truncate table table_name;
--刪除分區表一個分區的數據是
alter table table_name truncate partition p5;
注:分區根據具體情況選擇。
表分區有以下優點:
1、數據查詢:數據被存儲到多個文件上,減少了I/O負載,查詢速度提高。
2、數據修剪:保存歷史數據非常的理想。
3、備份:將大表的數據分成多個文件,方便備份和恢復。
4、並行性:可以同時向表中進行DML操作,並行性性能提高。
================================================
四、分區索引:
1、一般索引:create index index_name on table(col_name);
2、Oracle 分區索引詳解
語法:Table Index
CREATE [UNIQUE|BITMAP] INDEX [schema.]index_name
ON [schema.]table_name [tbl_alias]
(col [ASC | DESC]) index_clause index_attribs
index_clauses:
分以下兩種情況
1. Local Index
就是索引信息的存放位置依賴於父表的Partition信息,換句話說創建這樣的索引必須保證父表是Partition
1.1 索引信息存放在父表的分區所在的表空間。但是僅可以創建在父表為HashTable或者composite分區表的。
LOCAL STORE IN (tablespace)
1.2 僅可以創建在父表為HashTable或者composite分區表的。並且指定的分區數目要與父表的分區數目要一致
LOCAL STORE IN (tablespace) (PARTITION [partition [LOGGING|NOLOGGING] [TABLESPACE {tablespace|DEFAULT}] [PCTFREE int] [PCTUSED int] [INITRANS int] [MAXTRANS int] [STORAGE storage_clause] [STORE IN {tablespace_name|DEFAULT] [SUBPARTITION [subpartition [TABLESPACE tablespace]]]])
1.3 索引信息存放在父表的分區所在的表空間,這種語法最簡單,也是最常用的分區索引創建方式。
Local
1.4 並且指定的Partition 數目要與父表的Partition要一致
LOCAL (PARTITION [partition
[LOGGING|NOLOGGING]
[TABLESPACE {tablespace|DEFAULT}]
[PCTFREE int]
[PCTUSED int]
[INITRANS int]
[MAXTRANS int]
[STORAGE storage_clause]
[STORE IN {tablespace_name|DEFAULT]
[SUBPARTITION [subpartition [TABLESPACE tablespace]]]])
Global Index
索引信息的存放位置與父表的Partition信息完全不相干。甚至父表是不是分區表都無所謂的。語法如下:
GLOBAL PARTITION BY RANGE (col_list)
( PARTITION partition VALUES LESS THAN (value_list)
[LOGGING|NOLOGGING]
[TABLESPACE {tablespace|DEFAULT}]
[PCTFREE int]
[PCTUSED int]
[INITRANS int]
[MAXTRANS int]
[STORAGE storage_clause] )
但是在這種情況下,如果父表是分區表,要刪除父表的一個分區都必須要更新Global Index ,否則索引信息不正確
ALTER TABLE TableName DROP PARTITION PartitionName Update Global Indexes
--查詢索引
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
注意:不能為散列分區或子分區創建全局索引。