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

realkid4發表於2011-08-29

 

Oracle 11g中推出的Interval-Partition特性,是針對Range型別分割槽的一種功能擴充。對連續資料型別的Range分割槽,如果插入的新資料值與當前分割槽均不匹配,Interval-Partition特性可以實現自動的分割槽建立。

 

目前的Interval-Partition支援的Range分割槽鍵型別只有numberdate兩種型別。在上面的示例中,我們已經演示了數字number型別的分割槽擴充,下面我們進行date型別演示。

 

1、 Interval-Partition for Date Range

 

筆者認為,相對於number型別的分割槽擴充,date型別interval-partition分割槽的應用空間更為廣泛。因為實際生產環境下使用某個特定日期範圍分割槽的場景非常多,比如特定年度的交易作為單獨分割槽。

 

同樣選擇Oracle 11R2scott使用者schema作為實驗環境。

 

 

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

 

SQL> conn scott/tiger@wilson ;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

Connected as scott

 

SQL> select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';

 

DEFAULT_TABLESPACE             TEMPORARY_TABLESPACE

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

USERS                          TEMP

 

 

我們利用dba_objects資料檢視建立分割槽表,使用last_ddl_time作為分割槽鍵。

 

 

SQL> create table t_part

  2  partition by range(last_ddl_time)

  3  interval (numtoyminterval(1,'year'))

  4  (

  5     partition p1 values less than (to_date('2003-1-1','yyyy-mm-dd'))

  6  )

  7  as

  8  select * from dba_objects where 1=0;

 

Table created

 

 

處理中間的interval(numtoyminterval(1,year)),該資料表和其他日期型別分割槽資料表沒有差異。Numtoyminterval表示使用年作為時間間隔,每一年作為一個分割槽間距。

 

同時,在定義資料表的時候,定義了一個儲存2003年之前所有資料的分割槽p1。此時,我們觀察資料字典情況。

 

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    USERS

 

 

SQL> select table_name, partition_name, high_value, tablespace_name from user_tab_partitions where table_name='T_PART';

 

TABLE_NAME PARTITION_ HIGH_VALUE           TABLESPACE_NAME

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

T_PART     P1         TO_DATE(' 2003-01-01 USERS

                       00:00:00', 'SYYYY-M

                      M-DD HH24:MI:SS', 'N

                      LS_CALENDAR=GREGORIA

 

 

分割槽p1為預定義分割槽。此時我們向其中插入資料。

 

 

SQL> insert into t_part select * from dba_objects where last_ddl_time

3 rows inserted

 

SQL> insert into t_part select * from dba_objects where last_ddl_time>to_date('2003-1-1','yyyy-mm-dd');

72599 rows inserted

 

SQL> commit;

Commit complete

 

 

此時,其中插入的資料已經與原有分割槽不匹配了。

 

 

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, tablespace_name, num_rows from user_tab_partitions where table_name='T_PART';

 

TABLE_NAME PARTITION_ HIGH_VALUE           TABLESPACE_NAME                  NUM_ROWS

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

T_PART     P1         TO_DATE(' 2003-01-01 USERS                                   3

                       00:00:00', 'SYYYY-M                               

                      M-DD HH24:MI:SS', 'N                                

                      LS_CALENDAR=GREGORIA                               

 

T_PART     SYS_P24    TO_DATE(' 2009-01-01 USERS                                   1

                       00:00:00', 'SYYYY-M                                

                      M-DD HH24:MI:SS', 'N                               

                      LS_CALENDAR=GREGORIA                               

 

T_PART     SYS_P21    TO_DATE(' 2010-01-01 USERS                               71678

                       00:00:00', 'SYYYY-M                               

                      M-DD HH24:MI:SS', 'N                               

                      LS_CALENDAR=GREGORIA                               

 

T_PART     SYS_P22    TO_DATE(' 2011-01-01 USERS                                 711

                       00:00:00', 'SYYYY-M                               

                      M-DD HH24:MI:SS', 'N                               

                      LS_CALENDAR=GREGORIA                                

 

T_PART     SYS_P23    TO_DATE(' 2012-01-01 USERS                                 209

                       00:00:00', 'SYYYY-M                               

                      M-DD HH24:MI:SS', 'N                               

                      LS_CALENDAR=GREGORIA                               

 

 

結論:對於date型別分割槽鍵的interval-partition分割槽表,當不符合分割槽條件的記錄,會自動生成分割槽進行儲存。

 

另外,如果要求對每週的資料劃分為分割槽,可以使用numtodsinterval函式。

 

 

INTERVAL(numtodsinterval(7,'day'))

 

 

2、 Partition Tablespace

 

分割槽表的建立目的,除了進行分割槽內區域性掃描、便於管理外,還可以透過將分割槽存放在不同的表空間做到平衡分散IO的目的。所以,對分割槽的表空間規劃,通常是DBA日常決策的一個重要內容。

 

interval-partition中,分割槽的建立不是預建立過程,而是系統自動生成。那麼,表空間storage如何規劃設計呢?

 

從上面的t_part資料分割槽表中,無論是資料表體,還是各個分割槽,都沒有顯示的指明資料分割槽的表空間儲存。從結果看,儲存的位置都是users表空間,而users表空間是使用者scott的預設表空間。

 

 

SQL> select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';

 

DEFAULT_TABLESPACE             TEMPORARY_TABLESPACE

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

USERS                          TEMP

 

 

說明:如果分割槽表沒有明確表示使用的分割槽表空間,Oracle會選擇使用者schema對應的表空間作為分割槽所在表空間。

 

如果進行部分執行表空間的工作,會如何呢?

 

首先,調整scott使用者對應的default tablespace

 

 

SQL>  select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SCOTT';

 

DEFAULT_TABLESPACE             TEMPORARY_TABLESPACE

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

SYSTEM                         TEMP

 

 

進行分割槽表建立。

 

 

SQL> create table t_part

  2  partition by range(sal)

  3  interval (1000)

  4  (

  5     partition p1 values less than (1000),

  6     partition p2 values less than (2000) tablespace SYSAUX

  7  )

  8  as

  9  select * from emp where sal<2000;

 

Table created

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    SYSTEM

T_PART     P2         TABLE PARTITION    SYSAUX

 

 

在沒有使用store in的情況下,我們可以使用tablespace關鍵字對特殊分割槽進行指定。如果沒有指定,則選擇使用者預設表空間。

 

 

SQL> insert into t_part select * from emp where sal>=2000;

6 rows inserted

 

SQL> commit;

Commit complete

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    SYSTEM

T_PART     P2         TABLE PARTITION    SYSAUX

T_PART     SYS_P25    TABLE PARTITION    SYSTEM

T_PART     SYS_P26    TABLE PARTITION    SYSTEM

T_PART     SYS_P27    TABLE PARTITION    SYSTEM

 

 

如果沒有明確的指定表空間,Oracle會將建立的分割槽段儲存在所屬使用者schema對應的預設表空間裡。如果需要對預定義分割槽進行分割槽指定,需要使用tablespace子句。

 

那麼,如果是一個未建立的分割槽,如何制定建立分割槽呢?可以使用store in子句。

 

 

SQL> create table t_part

  2  partition by range(sal)

  3  interval (1000) store in (test,PERFSTAT)

  4  (

  5     partition p1 values less than (1000),

  6     partition p2 values less than (2000)

  7  )

  8  as

  9  select * from emp where sal<2000;

 

Table created

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    SYSTEM

T_PART     P2         TABLE PARTITION    SYSTEM

 

//預定義分割槽而言,如果不使用tablespace子句,會建立在預設表空間中;

 

SQL> insert into t_part select * from emp where sal>=2000;

6 rows inserted

 

SQL> commit;

Commit complete

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    SYSTEM

T_PART     P2         TABLE PARTITION    SYSTEM

T_PART     SYS_P28    TABLE PARTITION    TEST

T_PART     SYS_P29    TABLE PARTITION    PERFSTAT

T_PART     SYS_P30    TABLE PARTITION    PERFSTAT

 

 

如果在store in後面標註上tablespaces的列表,那麼新建立出的分割槽就會依次迴圈的均勻存放在各個分割槽上。

 

 

SQL> insert into t_part (sal) values (6000);

1 row inserted

 

SQL> commit;

Commit complete

 

SQL> select segment_name, partition_name,SEGMENT_TYPE, tablespace_name from user_segments where segment_name='T_PART';

 

SEGMENT_NA PARTITION_ SEGMENT_TYPE       TABLESPACE_NAME

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

T_PART     P1         TABLE PARTITION    SYSTEM

T_PART     P2         TABLE PARTITION    SYSTEM

T_PART     SYS_P28    TABLE PARTITION    TEST

T_PART     SYS_P29    TABLE PARTITION    PERFSTAT

T_PART     SYS_P30    TABLE PARTITION    PERFSTAT

T_PART     SYS_P31    TABLE PARTITION    TEST

 

6 rows selected

 

 

使用store in子句,可以方便的指定未生成建立分割槽的表空間分佈。

 

3、 結論

 

Oracle 11g中,對於分割槽表技術提出了很多的新特性,包括新的子分割槽組織方法、Interval-Partition等等。Interval-Partition技術的推出,筆者認為還是建立在online生產環境的分割槽自動化管理理念上。在實際生產環境中,進行分割槽補充或者管理都需要在特定的維護視窗時間和預規劃工作。Oracle提供的Interval-Partition,可以幫助DBA實現很多的分割槽維護工作。

 

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

相關文章