11g分佈表新特性——Interval分割槽(上)

realkid4發表於2011-08-29

 

作為一個成熟的DBMS,在每個新的版本中Oracle都會推出一些有益的技術嘗試和新特性。熟悉掌握這些新特性,有助於我們更快的適應新版本Oracle軟體,掌握其發展動態脈絡,及時最佳化我們的工作方式。

 

分割槽表是我們經常使用的一種堆表最佳化手段。藉助分割槽表,我們可以將一個資料量巨大的表根據業務需求水平切分為不同的分割槽塊。將資料訪問處理和運維管理集中在特定的資料塊內部,以期減少全表大面積搜尋。

 

相對於普通資料表,分割槽表要花很多的規劃和管理精力。規劃包括分割槽型別的選擇、分割槽鍵選擇和物理段segment儲存分配。管理包括分割槽預留和新增、對應分割槽資料管理等等。

 

Oracle11g之前,分割槽表包括多少個分割槽,各分割槽都在什麼位置上是在建表過程中確定的。之後的修改需要手工完成。Oracle11g推出了間距Interval-Partition的特性,實現一些型別分割槽表的自動分割槽管理。

 

1、 Before Oracle11g

 

首先,我們來看看Interval-Partition出現之前的特性。Oracle DBA和開發人員對分割槽表通常是需要進行預分割槽規劃,也就是在部署系統的時候就預先建立出一些預留分割槽(通常出現在數字型別和日期型別,比如預先分配3年系統的資料分割槽)。因為如果資料表建立,特別是生產環境上的資料表建立,新增加和劃分分割槽就有很多維護視窗問題,所以DBA經常對資料表進行預先分割槽。

 

11g之前,如果資料中出現未能匹配分割槽條件的情況,系統會拒絕進行資料操作。

 

 

SQL> select * from v$version;

 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE    10.2.0.1.0  Production

 

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 - Production

 

 

我們構建一個簡單的Range-Partition Table

 

SQL> create table t_part

  2  (

  3    EMPNO    NUMBER(4) not null,

  4    ENAME    VARCHAR2(10),

  5    JOB      VARCHAR2(9),

  6    MGR      NUMBER(4),

  7    HIREDATE DATE,

  8    SAL      NUMBER(7,2),

  9    COMM     NUMBER(7,2),

 10    DEPTNO   NUMBER(2)

 11  )

 12  partition by range(sal)

 13  (

 14     partition t_p1 values less than (1000) tablespace users,

 15     partition t_p2 values less than (2000) tablespace system,

 16     partition t_p3 values less than (3000) tablespace mytest

 17  );

 

Table created

 

 

如果此時試圖插入資料,對未能對映到分割槽的資料是報錯提示的。

 

 

SQL> insert into t_part select * from scott.emp;

 

insert into t_part select * from scott.emp

 

ORA-14400: 插入的分割槽關鍵字未對映到任何分割槽

 

SQL> select count(*) from scott.emp where sal>=3000;

 

  COUNT(*)

----------

         3

 

 

結論:在Interval-Partition特性出現之前,DBA必須預先對將來可能出現的資料值進行規劃或者預測。如果是一個生產系統,Online狀態新增或者修改分割槽存在一些操作風險。

 

 

2、 Interval-Partition feature

 

Oracle 11g中,推出了Interval-Partition的新特性。Interval-Partition特性並不是提供了一種新的分割槽方案,而是提供了一種分割槽擴充方案。下面我們透過一個實驗來演示Interval-Partition的使用。

 

 

SQL> select * from v$version;

 

BANNER

-------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0  Production

 

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 Production

 

 

此時我們選擇Oracle 11r2版本進行試驗。

 

 

SQL> create table t_part

  2  (

  3    EMPNO    NUMBER(4) not null,

  4    ENAME    VARCHAR2(10),

  5    JOB      VARCHAR2(9),

  6    MGR      NUMBER(4),

  7    HIREDATE DATE,

  8    SAL      NUMBER(7,2),

  9    COMM     NUMBER(7,2),

 10    DEPTNO   NUMBER(2)

 11  )

 12  partition by range(sal)

 13  interval (1000)

 14  store in (users, system)

 15  (

 16     partition t_p1 values less than (1000),

 17     partition t_p2 values less than (2000),

 18     partition t_p3 values less than (3000)

 19  );

 

Table created

 

 

我們構建了一個和Oracle10g實驗基本類似的環境。分割槽表分割槽鍵和分割槽型別相同,唯一較大的差異在於中間新增了子句Interval(1000)。在Oracle中,分割槽表對應的資料段是多個,我們透過檢視dba_segments可以檢視到特性資訊。

 

 

SQL> select table_name, partition_name, high_value, PARTITION_POSITION, TABLESPACE_NAME from dba_tab_partitions where table_name='T_PART';

 

TABLE_NAME PARTITION_NAME       HIGH_VALUE PARTITION_POSITION TABLESPACE_NAME

---------- -------------------- ---------- ------------------ ------------------------------

T_PART     T_P1                 1000                        1 SYSTEM

T_PART     T_P2                 2000                        2 SYSTEM

T_PART     T_P3                 3000                        3 SYSTEM

 

 

包括了在定義資料表時確定的三個資料段,符合條件的對映值分別為100020003000。我們對分割槽表可以使用dbms_stats方法進行適當的統計量收集。

 

 

SQL> exec dbms_stats.gather_table_stats(user,'T_PART',cascade => true);

 

PL/SQL procedure successfully completed

 

SQL> select table_name, partition_name, high_value, PARTITION_POSITION, TABLESPACE_NAME, num_rows from dba_tab_partitions where table_name='T_PART';

 

TABLE_NAME PARTITION_NAME       HIGH_VALUE PARTITION_POSITION NUM_ROWS

---------- -------------------- ---------- ------------------ ----------

T_PART     T_P1                 1000                        1         0

T_PART     T_P2                 2000                        2         0

T_PART     T_P3                 3000                        3         0

 

 

接下來,向資料表t_part中灌入資料scott.t

 

 

SQL> insert into t_part select * from scott.emp;

14 rows inserted

 

SQL> commit;

Commit complete

 

SQL> select * from scott.emp;

 

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

----- ---------- --------- ----- ----------- --------- --------- ------

 7566 JONES      MANAGER    7839 1981/4/2      2975.00               20

7788 SCOTT      ANALYST    7566 1987/4/19     3000.00               20

 7839 KING       PRESIDENT       1981/11/17    5000.00               10

 (篇幅原因,有省略……

 7902 FORD       ANALYST    7566 1981/12/3     3000.00               20

 7934 MILLER     CLERK      7782 1982/1/23     1300.00               10

 

14 rows selected

 

 

 

注意:插入的資料中包括了大於等於3000的資料值,但是還是成功插入到了分割槽表中。我們檢查分割槽表段情況。

 

 

SQL> exec dbms_stats.gather_table_stats(user,'T_PART',cascade => true);

 

PL/SQL procedure successfully completed

 

SQL> select table_name, partition_name, high_value, PARTITION_POSITION, TABLESPACE_NAME, num_rows from dba_tab_partitions where table_name='T_PART';

 

TABLE_NAME PARTITION_NAME       HIGH_VALUE PARTITION_POSITION TABLESPACE_NAME        NUM_ROWS

---------- -------------------- ---------- ------------------ -------------------- ----------

T_PART     T_P1                 1000                        1 SYSTEM                        2

T_PART     T_P2                 2000                        2 SYSTEM                        6

T_PART     T_P3                 3000                        3 SYSTEM                        3

T_PART     SYS_P21              4000                        4 SYSTEM                        2

T_PART     SYS_P22              6000                        5 SYSTEM                        1

 

 

注意:原有的三個資料段變成了五個資料段。出現了兩個新的分割槽段sys_p21sys_p22,分別對應Range分割槽上線40006000。統計值中表明插入的三個異常值存在於其內。

 

這樣我們就能夠明白interval-partitionRange分割槽數字型別分割槽鍵的作用了。簡單的說,在定義分割槽表的時候,可以透過interval指定出一個分割槽擴充的規則方案。在例子中,我們選擇了sal變化1000的時候,進行擴充分割槽。之後,當Oracle在對這個資料表進行操作的時候,如果發生了超過原有分割槽範圍的情況,會按照1000的步長進行自動的分割槽建立。

 

例子中,我們有300030005000的異常值。兩個3000擴充為以4000作為less than的分割槽。5000的異常值自然擴充為以6000less than的分割槽。

 

 

數字型別分割槽鍵的interval分割槽在應對異常資料值和新增資料值可能的時候效果很好。Interval-Partition是在原有分割槽的基礎上,提供異常值分割槽擴充方法。同時這樣對一些有規則的分割槽擴充,就可以實現Oracle自動進行新分割槽的加入了。

 

目前,Oracle11g支援兩種型別的分割槽鍵進行Interval-Partitionnumber型別和date型別。下面我們對date日期型別變數的擴充分割槽使用進行試驗演示。

 

 

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

相關文章