ORACLE分割槽表梳理系列(二)- 分割槽表日常維護及注意事項

不一樣的天空w發表於2017-08-06
http://www.cnblogs.com/yumiko/p/6163523.html

前言:
    本文著重總結分割槽表的日常維護操作以及相應的注意事項。
    本文涉及的日常維護內容包括:

        增加分割槽(add)
        移動分割槽(move)
        截斷分割槽(truncate)
        刪除分割槽(drop)
        拆分分割槽(split)
        合併分割槽(merge)      --hash分割槽不適用
        交換分割槽(exchange)
        收縮分割槽(coalesce)   --僅適用於hash分割槽
    本文涉及一些非分割槽表至分割槽表的遷移方法的思路,以及一些日常維護操作在特殊情況下的處理方法。
    本文演示涉及的測試分割槽表,若無特殊建立或者說明,預設使用“測試表準備”部分提及的測試表。
    本文演示使用的資料庫版本為oracle 11.2.0.4。

需要注意:關於分割槽表日常維護操作,對於分割槽表索引的影響未提及,會在後面總結分割槽表索引時進行闡述說明。

 
1、測試表準備
為了便於具體的操作演示,首先準備一張RANGE型的測試分割槽表TEST_RANGE_PARTITION。
這裡的測試資料來源於oracle測試使用者scott下的emp表。

--建立分割槽表TEST_RANGE_PARTITION
--這裡透過dbms_metadata.get_ddl獲得emp表的建表結構進而修改
SQL> CREATE TABLE "SCOTT"."TEST_RANGE_PARTITION"
      (    "EMPNO" NUMBER(4,0),
           "ENAME" VARCHAR2(10),
           "JOB" VARCHAR2(9),
           "MGR" NUMBER(4,0),
           "HIREDATE" DATE,
           "SAL" NUMBER(7,2),
           "COMM" NUMBER(7,2),
           "DEPTNO" NUMBER(2,0)
      )
     PARTITION BY RANGE ("SAL")
      (PARTITION "TEST_RANGE_SAL_01" VALUES LESS THAN (1000),
       PARTITION "TEST_RANGE_SAL_02" VALUES LESS THAN (2000),
       PARTITION "TEST_RANGE_SAL_03" VALUES LESS THAN (3000),
       PARTITION "TEST_RANGE_SAL_MAX" VALUES LESS THAN (MAXVALUE)  
      );
Table created.


SQL> insert into TEST_RANGE_PARTITION select * from emp;

14 rows created.


SQL> commit;

Commit complete.

透過下面的方法,瞭解關於上面建立分割槽表的資料分佈基本情況。
複製程式碼

--查詢分表各分割槽的條件以及資料庫分佈情況
--可以看到此時NUM_ROWS列為空,主要是因為表的的統計資訊未收集導致。
SQL> select a.TABLE_NAME,PARTITIONING_TYPE,PARTITION_NAME,HIGH_VALUE,NUM_ROWS from user_part_tables a,user_tab_partitions b where a.TABLE_NAME=b.TABLE_NAME and a.table_name='TEST_RANGE_PARTITION';

TABLE_NAME                     PARTITION PARTITION_NAME       HIGH_VALUE    NUM_ROWS
------------------------------ --------- -------------------- ----------- ----------
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_01    1000
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_02    2000
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_03    3000
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_MAX   MAXVALUE

--收集分割槽表TEST_RANGE_PARTITION的統計資訊
SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.

--可以看到,此時各分割槽的資料情況已經顯示出來
SQL> select a.TABLE_NAME,PARTITIONING_TYPE,PARTITION_NAME,HIGH_VALUE,NUM_ROWS from user_part_tables a,user_tab_partitions b where a.TABLE_NAME=b.TABLE_NAME and a.table_name='TEST_RANGE_PARTITION';

TABLE_NAME                     PARTITION PARTITION_NAME       HIGH_VALUE    NUM_ROWS
------------------------------ --------- -------------------- ----------- ----------
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_01    1000                 2
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_02    2000                 6
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_03    3000                 3
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_MAX   MAXVALUE             3

透過上面的操作,已經成功建立了一張RANGE型的分割槽表。

下面將依託這張表,介紹分割槽表的日常維護操作。


2、增加分割槽維護操作(add)
增加分割槽維護操作,顧名思義,主要針對當前分割槽表進行新增新分割槽的操作。

當分割槽表存在預設條件分割槽,如:RANGE分割槽表的MAXVALUE分割槽、LIST分割槽表的DEFAULT分割槽,此時增加分割槽操作會報錯。

下面嘗試透過增加分割槽操作,直接為測試表增加分割槽TEST_RANGE_SAL_04

SQL> alter table TEST_RANGE_PARTITION add partition TEST_RANGE_SAL_04 values less than(4000);
alter table TEST_RANGE_PARTITION add partition TEST_RANGE_SAL_04 values less than(4000)
                                               *
ERROR at line 1:
ORA-14074: partition bound must collate higher than that of the last partition

可以看到,針對存在預設條件的分割槽表,無法執行增加分割槽操作。

解決辦法:
1、刪除原預設條件分割槽,待增加分割槽後,再重新新增預設條件分割槽。
2、使用拆分分割槽(split)的方式,後面介紹。

這裡,我們嘗試下解決辦法1的方法進行操作。
--刪除存在預設條件MAXVALUE的分割槽
SQL> alter table TEST_RANGE_PARTITION drop partition TEST_RANGE_SAL_MAX;

Table altered.

--重新收集分割槽表的統計資訊
SQL> analyze table TEST_RANGE_PARTITION compute statistics;
Table analyzed.

--觀察分割槽表的資訊,可以看到此時預設條件MAXVALUE的分割槽已經不存在
SQL> select a.TABLE_NAME,PARTITIONING_TYPE,PARTITION_NAME,HIGH_VALUE,NUM_ROWS from user_part_tables a,user_tab_partitions b where a.TABLE_NAME=b.TABLE_NAME and a.table_name='TEST_RANGE_PARTITION';

TABLE_NAME                     PARTITION PARTITION_NAME       HIGH_VALUE    NUM_ROWS
------------------------------ --------- -------------------- ----------- ----------
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_01    1000                 2
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_02    2000                 6
TEST_RANGE_PARTITION           RANGE     TEST_RANGE_SAL_03    3000                 3

--增加新分割槽TEST_RANGE_SAL_04
SQL> alter table TEST_RANGE_PARTITION add partition TEST_RANGE_SAL_04 values less than(4000);
Table altered.

--重新增加預設條件MAXVALUE分割槽
SQL> alter table TEST_RANGE_PARTITION add partition TEST_RANGE_SAL_MAX values less than(maxvalue);
Table altered.


透過上面的方法,已經完成了增加分割槽的操作。下面進一步驗證增加分割槽的操作。

--重新收集測試分割槽表的統計資訊
SQL> analyze table TEST_RANGE_PARTITION compute statistics;
Table analyzed.

--檢視分割槽表資訊,可以看到上面增加的新分割槽
SQL> select a.TABLE_NAME,PARTITIONING_TYPE,PARTITION_NAME,HIGH_VALUE,NUM_ROWS from user_part_tables a,user_tab_partitions b where a.TABLE_NAME=b.TABLE_NAME and a.table_name='TEST_RANGE_PARTITION';

TABLE_NAME            PARTITION PARTITION_NAME     HIGH_VALUE   NUM_ROWS
--------------------- --------- ------------------ ----------- ---------
TEST_RANGE_PARTITION  RANGE     TEST_RANGE_SAL_01  1000                2
TEST_RANGE_PARTITION  RANGE     TEST_RANGE_SAL_02  2000                6
TEST_RANGE_PARTITION  RANGE     TEST_RANGE_SAL_03  3000                3
TEST_RANGE_PARTITION  RANGE     TEST_RANGE_SAL_MAX MAXVALUE            0
TEST_RANGE_PARTITION  RANGE     TEST_RANGE_SAL_04  4000                0

需要注意的是:對於預設條件的分割槽進行刪除,其資料不會重分佈到其他分割槽,而是刪除資料。因此在生產環境使用需慎重。
至此,增加分割槽維護操作的介紹結束。
 
3、移動分割槽維護操作(move)
移動分割槽維護操作,主要是將分割槽從一個表空間遷移至另一個表空間中。

--檢視當前分割槽對應的表空間情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME       TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02    USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03    USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01    USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX   USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04    USERS

--執行移動分割槽操作
SQL> alter table TEST_RANGE_PARTITION move partition TEST_RANGE_SAL_01 tablespace PARTITION_TS;
Table altered.

--驗證移動後,分割槽所在的表空間
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME       TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02    USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03    USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01    PARTITION_TS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX   USERS
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04    USERS


需要注意的是:
對於組合分割槽,無法直接移動分割槽,否則會丟擲ORA-14257錯誤,示例如下:

--準備一張list-list的組合分割槽表
SQL> CREATE TABLE "EMPLOYEE_LIST_LIST_PART"
      ( "EMPNO" NUMBER(4,0),
        "ENAME" VARCHAR2(10),
        "JOB" VARCHAR2(9),
        "MGR" NUMBER(4,0),
        "HIREDATE" DATE,
        "SAL" NUMBER(7,2),
        "COMM" NUMBER(7,2),
        "DEPTNO" NUMBER(2,0)
     )
     PARTITION BY LIST (DEPTNO)
     SUBPARTITION BY LIST (JOB)
     (
     PARTITION EMPLOYEE_DEPTNO_10 VALUES (10)
       ( SUBPARTITION EMPLOYEE_10_JOB_MAGAGER VALUES ('MANAGER'),
         SUBPARTITION EMPLOYEE_10_JOB_DEFAULT VALUES (DEFAULT)
       ),
     PARTITION EMPLOYEE_DEPTNO_20 VALUES (20)
       ( SUBPARTITION EMPLOYEE_20_JOB_MAGAGER VALUES ('MANAGER'),
         SUBPARTITION EMPLOYEE_20_JOB_DEFAULT VALUES (DEFAULT)
       ),
     PARTITION EMPLOYEE_DEPTNO_OTHERS VALUES (DEFAULT)
       ( SUBPARTITION EMPLOYEE_30_JOB_MAGAGER VALUES ('MANAGER'),
         SUBPARTITION EMPLOYEE_30_JOB_DEFAULT VALUES (DEFAULT)
       )
     );

Table created.

--檢視當前該組合分割槽所在表空間的資訊
SQL> select TABLE_NAME,PARTITION_NAME,SUBPARTITION_NAME,TABLESPACE_NAME from user_tab_subpartitions;

TABLE_NAME              PARTITION_NAME         SUBPARTITION_NAME        TABLESPACE_NAME
----------------------- ---------------------- ------------------------ ---------------
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_10     EMPLOYEE_10_JOB_MAGAGER  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_10     EMPLOYEE_10_JOB_DEFAULT  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_20     EMPLOYEE_20_JOB_MAGAGER  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_20     EMPLOYEE_20_JOB_DEFAULT  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_OTHERS EMPLOYEE_30_JOB_MAGAGER  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_OTHERS EMPLOYEE_30_JOB_DEFAULT  USERS


--移動組合分割槽表的區分
SQL> alter table EMPLOYEE_LIST_LIST_PART  move partition EMPLOYEE_DEPTNO_20 tablespace PARTITION_TS;
alter table EMPLOYEE_LIST_LIST_PART  move partition EMPLOYEE_DEPTNO_20 tablespace PARTITION_TS
                                                    *
ERROR at line 1:
ORA-14257: cannot move partition other than a Range, List, System, or Hash partition

透過上面的演示,可以清楚的看到,對於組合分割槽,無法直接移動分割槽至新的表空間。

 
解決辦法:
移動分割槽表的子分割槽,然後修改當前所在分割槽的屬性即可。具體演示如下:

--移動子分割槽
SQL> alter table EMPLOYEE_LIST_LIST_PART  move subpartition EMPLOYEE_20_JOB_MAGAGER tablespace PARTITION_TS;
Table altered.

SQL> alter table EMPLOYEE_LIST_LIST_PART  move subpartition EMPLOYEE_20_JOB_DEFAULT tablespace PARTITION_TS;
Table altered.

--修改分割槽的預設屬性
SQL> ALTER TABLE EMPLOYEE_LIST_LIST_PART MODIFY DEFAULT ATTRIBUTES FOR PARTITION EMPLOYEE_DEPTNO_20 tablespace PARTITION_TS;

Table altered.

--驗證移動分割槽後的結果
SQL> select TABLE_NAME,PARTITION_NAME,SUBPARTITION_NAME,TABLESPACE_NAME from user_tab_subpartitions;

TABLE_NAME              PARTITION_NAME         SUBPARTITION_NAME        TABLESPACE_NAME
----------------------- ---------------------  -----------------------  ---------------
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_10     EMPLOYEE_10_JOB_MAGAGER  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_10     EMPLOYEE_10_JOB_DEFAULT  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_20     EMPLOYEE_20_JOB_MAGAGER  PARTITION_TS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_20     EMPLOYEE_20_JOB_DEFAULT  PARTITION_TS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_OTHERS EMPLOYEE_30_JOB_MAGAGER  USERS
EMPLOYEE_LIST_LIST_PART EMPLOYEE_DEPTNO_OTHERS EMPLOYEE_30_JOB_DEFAULT  USERS

可以看到,透過移動子分割槽的方法,完成了對於組合分割槽的移動操作。

 
4、截斷分割槽維護操作(truncate)
截斷分割槽維護操作,相對於傳統的delete操作,刪除資料的效率會更高。而且會降低高水位線。

演示如下:

--檢視當前測試表分割槽情況及分割槽中的記錄數
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions where PARTITION_NAME='TEST_RANGE_SAL_02' or PARTITION_NAME='TEST_RANGE_SAL_03';

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    6
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3


--執行截斷分割槽操作
SQL> alter table TEST_RANGE_PARTITION truncate partition TEST_RANGE_SAL_02;
Table truncated.

--重新收集最新的測試表的統計資訊
SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.


--驗證截斷操作後,分割槽的記錄數變化
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions where PARTITION_NAME='TEST_RANGE_SAL_02' or PARTITION_NAME='TEST_RANGE_SAL_03';

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3


從上面的演示中可以看到,透過truncate操作,測試表的TEST_RANGE_SAL_02分割槽資料被清空。至此,演示完畢。

 
5、刪除分割槽維護操作(drop
對於分割槽的刪除操作,需要注意,在刪除分割槽後,分割槽所記錄的資料,不會重分佈至其他分割槽中而是被一併刪除。

--檢查當前分割槽表的分割槽情況,以及資料的分佈情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01         PARTITION_TS             2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    0


--執行分割槽的刪除操作
SQL> alter table TEST_RANGE_PARTITION drop partition TEST_RANGE_SAL_04;

Table altered.

--再次檢查分割槽表的分割槽情況,以及資料的分佈情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;
TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01         PARTITION_TS             2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0

可以看到,分割槽的刪除操作不會影響資料的分佈情況。


6、拆分分割槽維護操作(split
在“增加分割槽維護操作”部分,提到了對於存在預設條件的分割槽表增加分割槽的的兩種辦法,這裡將介紹透過拆分分割槽的辦法來增加分割槽。

需要注意:在目標分割槽拆分後,被拆分的分割槽會按照拆分規則,將資料進行重分佈。

演示例項:
首先,將測試表的資料分佈還原至初建時的資料分佈態。

--清空測試分割槽表中的所有資料
SQL> truncate table TEST_RANGE_PARTITION;

Table truncated.

--重新載入測試分割槽表的資料
SQL> insert into TEST_RANGE_PARTITION select * from emp;

14 rows created.

SQL> commit;

Commit complete.

--重新收集測試表的統計資訊
SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.

--檢視此時,資料在分割槽間的分佈情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    6
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01         PARTITION_TS             2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    3

檢視此時,存在預設條件MAXVALUE的分割槽TEST_RANGE_SAL_MAX的具體資料資訊:
SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_MAX);

     EMPNO ENAME      JOB              MGR HIREDATE          SAL     COMM    DEPTNO
---------- ---------- --------- ---------- ------------ -------- -------- ---------
      7788 SCOTT      ANALYST         7566 19-APR-87        3000                 20
      7839 KING       PRESIDENT            17-NOV-81        5000                 10
      7902 FORD       ANALYST         7566 03-DEC-81        3000                 20
 

下面針對上面的分割槽TEST_RANGE_SAL_MAX進行拆分處理,其中:
將SAL>=3000且SAL<4000的資料放入新的分割槽TEST_RANGE_SAL_04。
將SAL>=4000的資料保留在分割槽TEST_RANGE_SAL_MAX中。


--針對目標分割槽,執行拆分分割槽維護操作
--依據上面的需求,將資料拆分至分割槽TEST_RANGE_SAL_04以及TEST_RANGE_SAL_MAX中
SQL> alter table TEST_RANGE_PARTITION split partition TEST_RANGE_SAL_MAX at (4000) into (partition TEST_RANGE_SAL_04,partition TEST_RANGE_SAL_MAX);

Table altered.


--檢視此時測試分割槽表的分割槽情況,以及資料分佈情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    6
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01         PARTITION_TS             2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    1
 

驗證分割槽中實際的資料內容:

SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_04);

     EMPNO ENAME      JOB              MGR HIREDATE            SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------ ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 19-APR-87          3000                    20
      7902 FORD       ANALYST         7566 03-DEC-81          3000                    20



SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_MAX);

     EMPNO ENAME      JOB              MGR HIREDATE            SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------ ---------- ---------- ----------
      7839 KING       PRESIDENT            17-NOV-81          5000                    10

可以看到,經過拆分,資料已按之前的需求,分別儲存在兩個分割槽中。


7、合併分割槽維護操作(merge
合併分割槽操作,主要是將不同的分割槽,透過分割槽的合併,進行整合。

需要注意:
    對於list分割槽,合併的分割槽無限制要求
    對於range分割槽,合併的分割槽必須相鄰,否則無法進行合併操作。
    對於hash分割槽,無法進行合併分割槽操作。

此外,對於range分割槽,下限值由邊界值較低的分割槽決定,上限值由邊界值較高的分割槽決定。

演示示例:
透過合併分割槽技術,將測試表的分割槽TEST_RANGE_SAL_01以及分割槽TEST_RANGE_SAL_02進行合併,具體如下:

--檢視當前分割槽表的分割槽情況
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_02         USERS                    6
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_01         PARTITION_TS             2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    1

--查詢分割槽TEST_RANGE_SAL_01、TEST_RANGE_SAL_02值分佈情況:
SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_01);

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17 00:00:00        800                    20
      7900 JAMES      CLERK           7698 1981-12-03 00:00:00        950                    30

SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_02);

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 1981-02-20 00:00:00       1600        300         30
      7521 WARD       SALESMAN        7698 1981-02-22 00:00:00       1250        500         30
      7654 MARTIN     SALESMAN        7698 1981-09-28 00:00:00       1250       1400         30
      7844 TURNER     SALESMAN        7698 1981-09-08 00:00:00       1500          0         30
      7876 ADAMS      CLERK           7788 1987-05-23 00:00:00       1100                    20
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    10

6 rows selected.


--進行合併分割槽操作
SQL> alter table TEST_RANGE_PARTITION merge partitions TEST_RANGE_SAL_01,TEST_RANGE_SAL_02 into partition TEST_RANGE_SAL_00;

Table altered.


--驗證合併分割槽後的結果
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    3
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    2
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    1
TEST_RANGE_PARTITION           TEST_RANGE_SAL_00         USERS                    8

SQL> select * from TEST_RANGE_PARTITION partition(TEST_RANGE_SAL_00);

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 1980-12-17 00:00:00        800                    20
      7900 JAMES      CLERK           7698 1981-12-03 00:00:00        950                    30
      7499 ALLEN      SALESMAN        7698 1981-02-20 00:00:00       1600        300         30
      7521 WARD       SALESMAN        7698 1981-02-22 00:00:00       1250        500         30
      7654 MARTIN     SALESMAN        7698 1981-09-28 00:00:00       1250       1400         30
      7844 TURNER     SALESMAN        7698 1981-09-08 00:00:00       1500          0         30
      7876 ADAMS      CLERK           7788 1987-05-23 00:00:00       1100                    20
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    10

8 rows selected.


 
8、交換分割槽維護操作(exchange
交換分割槽技術,主要是將一個非分割槽表的資料同“一個分割槽表的一個分割槽”進行資料交換。支援雙向交換,既可以從分割槽表的分割槽中遷移到非分割槽表,也可以從非分割槽表遷移至分割槽表的分割槽中。

原則上,非分割槽表的結構、資料分佈等,要符合分割槽表的目標分割槽的定義規則。

演示如下:
首先,清空測試分割槽表的資料
SQL> truncate table TEST_RANGE_PARTITION;

Table truncated.

---查詢:
SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_00         USERS                    0
 

---建立一張基於emp表,sal<2000的測試非分割槽表emp_test

SQL> create table emp_test as select * from emp where sal < 2000;

Table created.

SQL> select count(*) from emp_test;

  COUNT(*)
----------
         8

注意,此時非分割槽表的資料量為8條記錄。


---執行交換分割槽操作,觀察分割槽表的記錄變化,以及非分割槽表的記錄變化
---執行分割槽交換操作
SQL> alter table TEST_RANGE_PARTITION exchange PARTITION TEST_RANGE_SAL_00 with table emp_test;

Table altered.

SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.


SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_00         USERS                    8
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0

SQL> select count(*) from emp_test;

  COUNT(*)
----------
         0

可以看到,透過分割槽交換,非分割槽表的資料轉移至分割槽表中,同時非分割槽表的記錄被清除。
 

---再次執行交換分割槽操作,觀察分割槽表的記錄變化,以及非分割槽表的記錄變化
SQL> alter table TEST_RANGE_PARTITION exchange PARTITION TEST_RANGE_SAL_00 with table emp_test;

Table altered.

SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.


SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_00         USERS                    0

SQL> select count(*) from emp_test;

  COUNT(*)
----------
         8

可以看到,此時分割槽表的資料又再次轉移回至非分割槽表,證明了前面所述,分割槽交換技術,既可以從分割槽表的分割槽中遷移到非分割槽表,也可以從非分割槽表遷移至分割槽表的分割槽中。

注意:若非分割槽表的資料,不符合分割槽表的分割槽規則,此時交換會丟擲ORA-14099錯誤。

--清空上面測試非分割槽表的資料
SQL> truncate table emp_test;

Table truncated.

--載入emp的所有資料至該測試非分割槽表
--之所以使用測試非分割槽表,是考慮emp表以後做其他實驗時可能還需要其中的資料
--透過這樣操作,測試非分割槽表的資料,既存在sal<2000的資料,也存在sal>2000的資料
SQL> insert into emp_test select * from emp;

14 rows created.

SQL> commit;

Commit complete.

--嘗試交換分割槽,觀察結果
SQL> alter table TEST_RANGE_PARTITION exchange PARTITION TEST_RANGE_SAL_00 with table emp_test;
alter table TEST_RANGE_PARTITION exchange PARTITION TEST_RANGE_SAL_00 with table emp_test
                                                                                 *
ERROR at line 1:
ORA-14099: all rows in table do not qualify for specified partition

可以看到,由於TEST_RANGE_SAL_00分割槽的限制條件為sal<2000,而測試非分割槽表的資料包含了sal>2000的資料,因此交換失敗。


解決辦法:
透過without validation子句,可以避免資料校驗,而交換成功。但會存在與分割槽規則相悖的資料,因此該方法要慎重。

SQL> alter table TEST_RANGE_PARTITION exchange PARTITION TEST_RANGE_SAL_00 with table emp_test without validation;

Table altered.

SQL> analyze table TEST_RANGE_PARTITION compute statistics;

Table analyzed.


SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
TEST_RANGE_PARTITION           TEST_RANGE_SAL_03         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_00         USERS                   14
TEST_RANGE_PARTITION           TEST_RANGE_SAL_04         USERS                    0
TEST_RANGE_PARTITION           TEST_RANGE_SAL_MAX        USERS                    0

技術方案擴充套件思路:
若打算採用交換分割槽的方法,以實現非分割槽表到分割槽表的轉換,可以採用先建立一個只有預設條件的單一分割槽的分割槽表,在分割槽交換資料後,根據實際需要,透過前面提到的“拆分分割槽”的方法進行分割槽操作。即大表改分割槽表(交換分割槽+分割槽分裂)

 
9、收縮分割槽維護操作(coalesce
收縮分割槽維護操作,僅僅可以在hash分割槽以及組合分割槽的hash子分割槽上進行使用。
透過使用收縮分割槽技術,可以收縮當前hash分割槽的分割槽數量。
對於hash分割槽的資料,在收縮過程中,oracle會自動完成資料在分割槽間的重分佈

演示如下:
首先基於emp表的資料,建立一張hash分割槽表

SQL> CREATE TABLE "EMPLOYEE_HASH_PART"
      ( "EMPNO" NUMBER(4,0),
        "ENAME" VARCHAR2(10),
        "JOB" VARCHAR2(9),
        "MGR" NUMBER(4,0),
        "HIREDATE" DATE,
        "SAL" NUMBER(7,2),
        "COMM" NUMBER(7,2),
        "DEPTNO" NUMBER(2,0)
      )
      PARTITION BY HASH (ENAME)
      (
      PARTITION EMPLOYEE_PART01,
      PARTITION EMPLOYEE_PART02
     );  

Table created.

SQL> insert into EMPLOYEE_HASH_PART select * from emp;

14 rows created.

SQL> commit;

Commit complete.

SQL> analyze table EMPLOYEE_HASH_PART compute statistics;

Table analyzed.


SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
EMPLOYEE_HASH_PART             EMPLOYEE_PART02           USERS                    6
EMPLOYEE_HASH_PART             EMPLOYEE_PART01           USERS                    8

執行收縮分割槽操作
SQL> alter table EMPLOYEE_HASH_PART coalesce partition;

Table altered.

SQL> analyze table EMPLOYEE_HASH_PART compute statistics;

Table analyzed.


SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
EMPLOYEE_HASH_PART             EMPLOYEE_PART01           USERS                   14

可以看到,透過收縮分割槽,原本兩個分割槽整合到一個,而且資料也同時被整合。

需要注意:
當hash分割槽中只有一個分割槽時,此時無法進行收縮操作。

SQL> select TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,num_rows from user_tab_partitions;

TABLE_NAME                     PARTITION_NAME            TABLESPACE_NAME   NUM_ROWS
------------------------------ ------------------------- --------------- ----------
EMPLOYEE_HASH_PART             EMPLOYEE_PART01           USERS                   14

SQL> alter table EMPLOYEE_HASH_PART coalesce partition;
alter table EMPLOYEE_HASH_PART coalesce partition
            *
ERROR at line 1:
ORA-14285: cannot COALESCE the only partition of this hash partitioned table or index

至此,關於分割槽表的日常維護操作及注意事項總結結束,後續會抽時間總結分割槽表索引的維護。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31397003/viewspace-2143151/,如需轉載,請註明出處,否則將追究法律責任。

相關文章