oracle 分區表詳解


一、分區表的概述:

    Oracle的表分區功能通過改善可管理性、性能和可用性,從而為各式應用程序帶來了極大的好處。通常,分區可以使某些查詢以及維護操作的性能大大提高。此外,分區還可以極大簡化常見的管理任務,分區是構建千兆字節數據系統或超高可用性系統的關鍵工具。
    分區功能能夠將表、索引或索引組織表進一步細分為段,這些數據庫對象的段叫做分區。每個分區有自己的名稱,還可以選擇自己的存儲特性。從數據庫管理員的角度來看,一個分區后的對象具有多個段,這些段既可進行集體管理,也可單獨管理,這就使數據庫管理員在管理分區后的對象時有相當大的靈活性。

1、分區表的優點:

  (1)由於將數據分散到各個分區中,減少了數據損壞的可能性; 
  (2)可以對單獨的分區進行備份和恢復; 
  (3)可以將分區映射到不同的物理磁盤上,來分散IO; 
  (4)提高可管理性、可用性和性能。

2、什么時候用分區表

   (1) 單表過大,超過一定范圍,建議以g計算表,均可考慮用分區
  (2)歷史數據據需要剝離的
  (3)查詢特征非常明顯,比如是按整年、整月或者按某個范圍!

3、分區表的類型

   1、range分區,按范圍
   2、list分區,列舉分區
   3、hash分區,根據hash值進行的散列分區
   4、復合分區,9i開始,Oracle就包括了2種復合分區,RANGE-HASH和RANGE-LIST。在11g,Oracle一下就提供了4種復合分區:RANGE-RANGE、LIST-RANGE、LIST-HASH和LIST-LIST。

二、創建分區的舉例

1、range分區

create table p_table(
obj_id number(10),
object_id number(10),
object_name varchar2(128),
owner varchar2(30),
object_type varchar2(19),
created date)
partition by range (obj_id)
(partition obj_id1 values less than (20000),
partition obj_id2 values less than (40000),
partition obj_id3 values less than (60000),
partition obj_id4 values less than (80000),
partition obj_id5 values less than (99999));

2、list分區

create table l_table(
obj_id number(10),
object_id number(10),
object_name varchar2(128),
owner varchar2(30),
segment_type varchar2(19),
created date)
partition by LIST(segment_type)
(partition l_type1 values ('LOBINDEX') tablespace my_space1,
 partition l_type2 values ('VIEW') tablespace my_space2,
 partition l_type3 values ('TABLE') tablespace my_space2);

3、hash分區
create table h_table(
obj_id number(10),
object_id number(10),
object_name varchar2(128),
owner varchar2(30),
object_type varchar2(19),
created date)
partition by hash(object_id)
( partition h_objid1,
 partition h_objid2,
 partition h_objid3,
 partition h_objid4);

4、復合分區

Oracle11g一下就提供了4種復合分區:RANGE-RANGE、LIST-RANGE、LIST-HASH和LIST-LIST。

4.1range-range

CREATE TABLE r_r_table(
obj_id number(10),
object_id number(10),
object_name varchar2(128),
owner varchar2(30),
object_type varchar2(19),
created date)
PARTITION BY RANGE (CREATED)
SUBPARTITION BY RANGE (obj_id)
(PARTITION p_level1_1 VALUES LESS THAN (TO_DATE('2013-04-01','YYYY-MM-DD'))
(
SUBPARTITION p_level2_1 VALUES LESS THAN (40000),
SUBPARTITION p_level2_2 VALUES LESS THAN (80000),
SUBPARTITION p_level2_3 VALUES LESS THAN (maxvalue)
 ),
 PARTITION p_level1_2 VALUES LESS THAN (TO_DATE('2013-07-1', 'YYYY-MM-DD'))
(
SUBPARTITION p_level2_4 VALUES LESS THAN (40000),
SUBPARTITION p_level2_5 VALUES LESS THAN (80000),
SUBPARTITION p_level2_6 VALUES LESS THAN (maxvalue)
 ),
 PARTITION p_level1_3 VALUES LESS THAN (TO_DATE('2013-10-1', 'YYYY-MM-DD'))
(
SUBPARTITION p_level2_7 VALUES LESS THAN (40000),
SUBPARTITION p_level2_8 VALUES LESS THAN (80000),
SUBPARTITION p_level2_9 VALUES LESS THAN (maxvalue)
 )
 );

--注意,如果加了maxvalue,那么就不能add的方式添加分區了!

5、11g自動分區技術

CREATE TABLE auto_partition (
OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(128),
CREATED DATE)
PARTITION BY RANGE (CREATED)
INTERVAL(NUMTOYMINTERVAL(1, 'month'))
(PARTITION P0 VALUES LESS THAN (TO_DATE('1-1-2011', 'dd-mm-yyyy')));

這樣,就會每個月系統自動生成一個分區

--INTERVAL (NUMTODSINTERVAL(1,'day'))   表示每天
--INTERVAL (NUMTOYMINTERVAL(1,'YEAR'))   表示每年

三、分區操作

--添加分區

添加分區
ALTER TABLE mytest ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));

添加子分區
alter table mytest modify partition p3 add subpartition values less than(TO_DATE('2003-06-01','YYYY-MM-DD'));

說明:如果采用了maxvalue,則不能用add,而應該采用split

--刪除分區

刪除分區
ALTER TABLE mytest DROP PARTITION P3;

刪除子分區
ALTER TABLE mytest DROP SUBPARTITION P4SUB1;

說明,如果表只剩下一個分區了,則不能drop,而應該drop表。在復合分區中,如果一個分區只剩下一個子分區,也不能drop

--truncate 分區

truncate分區
ALTER TABLE mytest TRUNCATE PARTITION P2;

truncate子分區

ALTER TABLE mytest TRUNCATE SUBPARTITION P2SUB1;

--合並分區

ALTER TABLE mytest MERGE PARTITIONS P1,P2 INTO PARTITION P2;

注意:不能將分區合並到界限較低的分區。以下代碼實現了P1 P2分區的合並

--拆分分區

ALTER TABLE mytest split PARTITION P2 AT(TO_DATE('2013-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);

--接合分區

ALTER TABLE mytest COALESCA PARTITION;

說明:這個只能用於hash分區

--重命名分區

ALTER TABLE mytest RENAME PARTITION P21 TO P2;

--分區表的查詢

SQL> select * from r_r_table subpartition(p_level2_1);       --查詢子分區

no rows selected

SQL> select * from r_r_table partition(p_level1_1);          --查詢分區

no rows selected

--分區表索引重建

Alter index ind_mytest rebuild partition p1 ;

alter index ind_created_test rebuild subpartition p_level2_5 online;

五、性能比較

SQL> set autot trace exp;
SQL> set linesize 400;


5.1非並行下的表范圍掃描

--分區表掃描的執行計划

SQL> select * from penggj.p_table where obj_id between 10000 and 30000;

Execution Plan
----------------------------------------------------------
Plan hash value: 1095083444

----------------------------------------------------------------------------------------------------
| Id  | Operation                | Name    | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |         | 14865 |  1872K|    99   (8)| 00:00:02 |       |       |
|   1 |  PARTITION RANGE ITERATOR|         | 14865 |  1872K|    99   (8)| 00:00:02 |     1 |     2 |
|*  2 |   TABLE ACCESS FULL      | P_TABLE | 14865 |  1872K|    99   (8)| 00:00:02 |     1 |     2 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("OBJ_ID">=10000 AND "OBJ_ID"<=30000)

Note
-----
   - dynamic sampling used for this statement (level=2)

--普通表全表掃描的執行計划

SQL> select * from penggj.n_table where obj_id between 10000 and 30000;

Execution Plan
----------------------------------------------------------
Plan hash value: 2316247272

-----------------------------------------------------------------------------
| Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |         | 22714 |  2861K|   193   (2)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| N_TABLE | 22714 |  2861K|   193   (2)| 00:00:03 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJ_ID">=10000 AND "OBJ_ID"<=30000)

Note
-----
   - dynamic sampling used for this statement (level=2)

說明:從上面兩個查詢的執行計划來看分區表效率更高,因為在整個掃描過程中,分區表只掃描了兩個分區,而普通表進行了全表掃描!


5.1並行下的表范圍掃描

--分區表范圍掃描

SQL> select /*+ parallel(p_table,4)*/ * from penggj.p_table where obj_id between 10000 and 30000;

Execution Plan
----------------------------------------------------------
Plan hash value: 2269943597

------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          | 14865 |  1872K|    27   (4)| 00:00:01 |       |       |        |      |            |
|   1 |  PX COORDINATOR      |          |       |       |            |          |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000 | 14865 |  1872K|    27   (4)| 00:00:01 |       |       |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX BLOCK ITERATOR |          | 14865 |  1872K|    27   (4)| 00:00:01 |     1 |     2 |  Q1,00 | PCWC |            |
|*  4 |     TABLE ACCESS FULL| P_TABLE  | 14865 |  1872K|    27   (4)| 00:00:01 |     1 |     2 |  Q1,00 | PCWP |            |
------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("OBJ_ID">=10000 AND "OBJ_ID"<=30000)

Note
-----
   - dynamic sampling used for this statement (level=2)


--普通表采用並行的方式進行

SQL> select /*+ parallel(p_table,4)*/ * from penggj.n_table where obj_id between 10000 and 30000;

Execution Plan
----------------------------------------------------------
Plan hash value: 2316247272

-----------------------------------------------------------------------------
| Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |         | 22714 |  2861K|   193   (2)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| N_TABLE | 22714 |  2861K|   193   (2)| 00:00:03 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJ_ID">=10000 AND "OBJ_ID"<=30000)

Note
-----
   - dynamic sampling used for this statement (level=2)

比較可以看到分區表采用並行的方式,其存在明顯的性能優勢!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM