Oracle 12c Study之-- 分区表新特性

时间:2021-09-19 20:41:40

Oracle 12c Study之-- 分区表新特性


数据库版本:

12:05:07 SYS@prod>select * from v$version;

 

BANNER                                                      CON_ID

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

Oracle Database 12c Enterprise Edition Release12.1.0.2.0 - 64bit Production      0

PL/SQL Release 12.1.0.2.0 - Production                           0

CORE   12.1.0.2.0      Production                               0

TNS for Linux: Version 12.1.0.2.0 - Production                    0

NLSRTL Version 12.1.0.2.0 - Production                            0

Elapsed: 00:00:00.03                           

一、   参考性分区新特性

在参考性分区增加间隔分区的功能,当父表增加新的分区时,子表扩展分区时,也会扩展同样的分区。

案例:                                                                                                                       

11:56:33 SCOTT@ prod>create table new_orders                                                                           

12:03:04   2   partition by range (order_date)                                                                        

12:03:04   3   INTERVAL(NUMTOYMINTERVAL(1, 'month')) store in(tbs1,tbs2,tbs3,tbs4)                                    

12:03:04   4   (partition p1 values less than (to_date('2005-04-01','yyyy-mm-dd'))tablespace tbs1,                   

12:03:04   5   partition p2 values less than (to_date('2005-07-01','yyyy-mm-dd'))tablespace tbs2,                    

12:03:04   6   partition p3 values less than (to_date('2005-10-01','yyyy-mm-dd'))tablespace tbs3,                    

12:03:04   7   partition p4 values less than (to_date('2006-01-01','yyyy-mm-dd'))tablespace tbs4)                    

12:03:04   8   as                                                                                                     

12:03:04   9   select * from orders;                                                                                                                                                                                                         

Table created.  

插入数据:

insert into new_ordersvalues(101,to_date('2005-02-03','yyyy-mm-dd'),'x1',1001,1,20000,88001,88002);

insert into new_ordersvalues(102,to_date('2005-05-15','yyyy-mm-dd'),'x1',1002,1,30000,88002,88002);

insert into new_orders values(103,to_date('2005-09-22','yyyy-mm-dd'),'x1',1003,1,40000,88003,88002);

insert into new_ordersvalues(104,to_date('2005-12-30','yyyy-mm-dd'),'x1',1004,1,10000,88004,88002);

 

12:06:24 SCOTT@ prod>col partition_name fora20                                                                                                                                                  

12:06:37 SCOTT@ prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments   

wheresegment_name='NEW_ORDERS'                                                       

                                                                                  

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME              

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

NEW_ORDERS          TABLE PARTITION    P1                   TBS1                         

NEW_ORDERS          TABLE PARTITION    P2                   TBS2                         

NEW_ORDERS          TABLE PARTITION    P3                   TBS3                         

NEW_ORDERS          TABLE PARTITION    P4                   TBS4  

 

在父表上建立主键:

12:06:37 SCOTT@ prod>alter table new_orders add constraint pk_new_orders primarykey(order_id); 

Table altered.

 

建立参考分区:

12:08:06 SCOTT@ prod>CREATE TABLE order_items

12:09:35   2      ( order_id           NUMBER(12)NOT NULL,

12:09:35   3        line_item_id       NUMBER(3)  NOT NULL,

12:09:35   4        product_id         NUMBER(6)  NOT NULL,

12:09:35   5        unit_price         NUMBER(8,2),

12:09:35   6        quantity           NUMBER(8),

12:09:35   7        CONSTRAINT order_items_fk

12:09:35   8        FOREIGN KEY(order_id) REFERENCESnew_orders(order_id)

12:09:35   9      )

12:09:35  10   PARTITION BY REFERENCE(order_items_fk);

Table created.

 

插入测试数据:

insert into order_itemsvalues(101,801,200001,200,100);

insert into order_itemsvalues(102,802,200002,300,100);

insert into order_itemsvalues(103,803,200003,400,100);

insert into order_itemsvalues(104,804,200004,100,100);

 

12:10:39 SCOTT@ prod>select* from order_items;

  ORDER_IDLINE_ITEM_ID PRODUCT_ID UNIT_PRICE  QUANTITY

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

       101          801     200001        200        100

       102          802     200002       300        100

       103          803     200003        400        100

       104          804     200004        100        100

 

Elapsed: 00:00:00.34            

 

12:12:46 SCOTT@ prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:12:53  2  where segment_name in ('NEW_ORDERS','ORDER_ITEMS');

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

ORDER_ITEMS         TABLE PARTITION    P1                   TBS1

NEW_ORDERS          TABLE PARTITION    P1                   TBS1

ORDER_ITEMS         TABLE PARTITION    P3                   TBS3

ORDER_ITEMS         TABLE PARTITION    P2                   TBS2

NEW_ORDERS          TABLE PARTITION    P3                   TBS3

NEW_ORDERS          TABLE PARTITION    P2                   TBS2

ORDER_ITEMS         TABLE PARTITION    P4                   TBS4

NEW_ORDERS          TABLE PARTITION    P4                   TBS4

 

父表中插入数据,超越分区范围:

12:13:00 SCOTT@ prod>insert into new_ordersvalues(105,to_date('2006-02-01','yyyy-mm-dd'),'x1',1005,1,10000,88005,88002);

1 row created.

 

12:16:31 SCOTT@ prod>commit;

Commit complete.

12:16:34 SCOTT@ prod>select * from new_orders;

 

  ORDER_IDORDER_DAT PROD_NAME  LINE_ITEM_ID  CHANNE_ID PRODUCT_ID UNIT_PRICE        QTY

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

       10103-FEB-05 x1                 1001          1     20000      88001      88002

       10215-MAY-05 x1                 1002          1     30000      88002      88002

       10322-SEP-05 x1                 1003          1     40000      88003      88002

       10430-DEC-05 x1                 1004          1     10000      88004      88002

       10501-FEB-06 x1                 1005          1     10000      88005      88002

 

父表自动扩展一个新的分区:

12:17:17 SCOTT@ prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:17:34   2  where segment_name in ('NEW_ORDERS','ORDER_ITEMS') order by 1;

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

NEW_ORDERS           TABLE PARTITION    SYS_P346             TBS2

NEW_ORDERS          TABLE PARTITION    P2                   TBS2

NEW_ORDERS          TABLE PARTITION    P3                   TBS3

NEW_ORDERS          TABLE PARTITION    P4                   TBS4

NEW_ORDERS          TABLE PARTITION    P1                   TBS1

ORDER_ITEMS         TABLE PARTITION    P2                   TBS2

ORDER_ITEMS         TABLE PARTITION    P3                   TBS3

ORDER_ITEMS         TABLE PARTITION    P4                   TBS4

ORDER_ITEMS         TABLE PARTITION    P1                   TBS1

 

9 rows selected.

在子表中插入超出分区范围的数据:

12:17:49 SCOTT@ prod>insert into order_items values(105,805,200005,100,100);

1 row created.

12:19:55 SCOTT@ prod>commit;

Commit complete.

 

子表也自动扩展一个新的分区,且分区名和父表分区名相同:

12:19:57 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:20:05   2 where segment_name in ('NEW_ORDERS','ORDER_ITEMS') order by 1;

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

NEW_ORDERS          TABLE PARTITION    P1                   TBS1

NEW_ORDERS          TABLE PARTITION    P2                   TBS2

NEW_ORDERS          TABLE PARTITION    P3                   TBS3

NEW_ORDERS           TABLE PARTITION    SYS_P346             TBS2

NEW_ORDERS          TABLE PARTITION    P4                   TBS4

ORDER_ITEMS         TABLE PARTITION    P4                   TBS4

ORDER_ITEMS         TABLE PARTITION    P3                   TBS3

ORDER_ITEMS          TABLE PARTITION    SYS_P346             TBS2

ORDER_ITEMS         TABLE PARTITION    P1                   TBS1

ORDER_ITEMS         TABLE PARTITION    P2                   TBS2

10 rows selected.

 

二、多分区操作和管理

 

1) 增加多个新分区

在Oracle 12c R1之前,一次只可能添加一个新分区到一个已存在的分区表。要添加一个以上的新分区,需要对每个新分区都单独执行一次ALTER TABLE ADD PARTITION语句。而Oracle 12c只需要使用一条单独的ALTER TABLE ADD PARTITION 命令就可以添加多个新分区,这增加了数据库灵活性。以下示例说明了如何添加多个新分区到已存在的分区表:

 

12:22:48 SCOTT@ prod>CREATE TABLE  t1_part (enonumber(8), ename varchar2(40), sal number (6))

12:44:27   2  PARTITION BY RANGE (sal)

12:44:27   3 (PARTITION p1 VALUES LESS THAN (10000),

12:44:27   4 PARTITION p2 VALUES LESS THAN (20000),

12:44:27   5 PARTITION p3 VALUES LESS THAN (30000) );

Table created.

 

12:44:28 SCOTT@ prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:44:35   2 where segment_name='T1_PART';

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T1_PART             TABLE PARTITION    P1                   USERS

T1_PART             TABLE PARTITION    P2                   USERS

T1_PART             TABLE PARTITION    P3                   USERS

 

增加多个新分区到表中:

12:50:45 SCOTT@prod>ALTER TABLE t1_part ADD PARTITION p4 VALUES LESS THAN (35000),PARTITION p5 VALUES LESS THAN (40000);

Table altered.

12:51:07 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME from user_segments

12:51:50   2 where segment_name='T1_PART';

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T1_PART             TABLE PARTITION    P1                   USERS

T1_PART             TABLE PARTITION    P2                   USERS

T1_PART             TABLE PARTITION    P3                   USERS

T1_PART              TABLE PARTITION    P4                   USERS

T1_PART              TABLE PARTITION    P5                  USERS

同样,只要MAXVALUE分区不存在,你就可以添加多个新分区到一个列表和系统分区表。

 

2) 同时截断多个分区

作为数据维护的一部分,DBA通常会在一个分区表上进行删除或截断分区的维护任务。在12c R1之前,对于一个已存在的分区表一次只可能删除或截断一个分区。而对于Oracle12c, 可以用单条ALTER TABLE table_name {DROP|TRUNCATE}PARTITIONS 命令来撤销或合并多个分区和子分区。

 

12:53:00 SCOTT@ prod>ALTERTABLE t1_part TRUNCATE partitions p4,p5;

Table truncated.

 

12:53:39 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:53:45   2 where segment_name='T1_PART';

 

SEGMENT_NAME        SEGMENT_TYPE       PARTITION_NAME       TABLESPACE_NAME

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

T1_PART             TABLE PARTITION    P1                   USERS

T1_PART             TABLE PARTITION    P2                   USERS

T1_PART             TABLE PARTITION    P3                   USERS

T1_PART             TABLE PARTITION    P4                   USERS

T1_PART             TABLE PARTITION    P5                   USERS

Elapsed: 00:00:00.02

3) 同时删除多个分区

4)  

12:53:48 SCOTT@prod>alter table t1_part drop partitions p4,p5;

Table altered.

 

12:54:19 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAMEfrom user_segments

12:54:24   2 where segment_name='T1_PART';

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME       TABLESPACE_NAME

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

T1_PART             TABLE PARTITION    P1                   USERS

T1_PART             TABLE PARTITION    P2                   USERS

T1_PART             TABLE PARTITION    P3                   USERS

Elapsed: 00:00:00.02

 

截断、删除分区时同时更新全局索引

要保持索引更新,使用UPDATE INDEXES或UPDATE GLOBAL INDEXES语句,如下所示:

12:56:09 SCOTT@prod>ALTER TABLE t1_part TRUNCATE partitions p2,p3 update global indexes;

Table truncated.

 

12:57:09 SCOTT@prod>ALTER TABLE t1_part dop  partitionsp2,p3 update global indexes;

如果你在不使用UPDATE GLOBAL INDEXES 语句的情况下删除或截断一个分区,你可以在USER_INDEXES或USER_IND_PARTITIONS 字典视图下查询ORPHANED_ENTRIES字段以找出是否有索引包含任何的过期条目。

 

5) 同时拆分多个分区:

在12c中新增强的SPLIT PARTITION 语句可以让你只使用一个单独命令将一个特定分区或子分区分割为多个新分区。

12:57:59 SCOTT@prod>CREATE TABLE t2_part (eno number(8), ename varchar2(40), sal number(6))

12:58:11   2 PARTITION BY RANGE (sal)

12:58:14   3 (PARTITION p1 VALUES LESS THAN (10000),

12:58:18   4 PARTITION p2 VALUES LESS THAN (20000),

12:58:21   5 PARTITION p_max VALUES LESS THAN (MAXVALUE) );

Table created.

 

12:58:30 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

12:58:36   2  where segment_name='T2_PART';

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T2_PART             TABLE PARTITION    P1                   USERS

T2_PART             TABLE PARTITION    P2                   USERS

T2_PART             TABLE PARTITION    P_MAX                USERS

Elapsed: 00:00:00.03

 

12:58:56 SCOTT@prod>ALTER TABLE t2_part

13:00:23   2 SPLIT PARTITION p_max INTO

13:00:23   3  (PARTITION p3 VALUES LESS THAN (25000),

13:00:23   4 PARTITION p4 VALUES LESS THAN (30000),

13:00:23   5 PARTITION p_max);

Table altered.

13:00:24 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

13:00:36   2 where segment_name='T2_PART';

 

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T2_PART             TABLE PARTITION    P1                   USERS

T2_PART             TABLE PARTITION    P2                   USERS

T2_PART             TABLE PARTITION    P3                   USERS

T2_PART             TABLE PARTITION    P4                   USERS

T2_PART             TABLE PARTITION    P_MAX                USERS

Elapsed: 00:00:00.04

 

6) 同时合并多个分区

你可以使用单条ALTER TBALE MERGE PARTITIONS 语句将多个分区合并为一个单独分区:

13:00:39 SCOTT@prod> CREATE TABLE t3_part (eno number(8), ename varchar2(40), sal number(6))

13:02:12   2 PARTITION BY RANGE (sal)

13:02:12   3  (PARTITION p1 VALUES LESS THAN (10000),

13:02:12   4 PARTITION p2 VALUES LESS THAN (20000),

13:02:12   5 PARTITION p3 VALUES LESS THAN (30000),

13:02:12   6  PARTITION p4 VALUES LESS THAN (40000),

13:02:12   7  PARTITION p5 VALUES LESS THAN (50000),

13:02:12   8  PARTITION  p_max VALUES LESSTHAN  (MAXVALUE) );

Table created.

 

13:02:14 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

13:02:21   2   where segment_name='T3_PART';

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T3_PART             TABLE PARTITION    P_MAX                USERS

T3_PART             TABLE PARTITION    P5                   USERS

T3_PART             TABLE PARTITION    P4                   USERS

T3_PART             TABLE PARTITION    P3                   USERS

T3_PART             TABLE PARTITION    P2                   USERS

T3_PART             TABLE PARTITION    P1                   USERS

 

如果分区范围形成序列,你可以使用如下示例:

13:06:12 SCOTT@prod>alter table t3_part merge partitions p2 to p3 into partition p_m23;

Table altered.

13:06:38 SCOTT@prod>select segment_name,segment_type,PARTITION_NAME,TABLESPACE_NAME fromuser_segments

13:06:44   2 where segment_name='T3_PART';

SEGMENT_NAME        SEGMENT_TYPE      PARTITION_NAME      TABLESPACE_NAME

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

T3_PART             TABLE PARTITION    P1                   USERS

T3_PART             TABLE PARTITION    P_M23                USERS

T3_PART              TABLE PARTITION    P_MAX                USERS

T3_PART             TABLE PARTITION    P_MERG               USERS