截断分区

截断分区:可以快速删除一个分区表中所有行。

使用ALTER TABLE … TRUNCATE PARTITION语句截断分区,截断分区操作类似于删除分区操作,但截断分区操作只是清空的它的数据,不是物理删除。不可以截断一个索引分区。不过,如果为表定义了局部分区索引,在对表分区执行截断分区操作时会同步截断所有与该分区对应的局部索引分区。 如果未指定UPDATE INDEXES,全局索引和全局分区索引将会标记为UNUSABLE状态,需要重建。类似,可以删除一个复合分区表中某个子分区表中的所有行。 相应局部索引子分区也将被截断。

另外,若操作对象是分区表,可以在上述操作的 SQL 语句后添加 UPDATE INDEXES 子句,以便维护全局索引。这样对索引进行维护的好处有两个:

  • 在操作期间索引依然有效,使得其他应用程序不会受相关操作的影响。
  • 在操作结束后索引不必重建。

使用截断分区时,应注意以下规则:

  • 如果表上存在有效的外键约束,那么不允许截断子分区表;如果需要截断子分区表,则必须使此表上的外键约束无效。
  • 如果表包含lob列,那么lob列的段也会被截断。
  • 如果被截断的子分区表上有局部分区索引,而且状态是unusable,则截断后,索引的状态会被标识为usable,如果所有的局部子分区索引有效,则局部主分区索引被置为有效。
  • 截断之后,全局分区索引与全局非分区索引都将失效。

截断分区的方法有以下三种:

  • 方法一,在截断分区时保留全局索引在合适的位置
  • 方法二,在ALTER TABLE … TRUNCATE PARTITION之前使用DELETE语句删除分区表的行
  • 方法三,在ALTER TABLE语句中指定UPDATE INDEXS,这使得在截断分区表时同时截断全局索引

示例1:截断分区表的三种方法

--  清理环境
DROP INDEX pti;
DROP TABLE tab;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;

--  创建表空间
CREATE TABLESPACE ts1 DATAFILE 'ts1.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;
CREATE TABLESPACE ts2 DATAFILE 'ts2.dt' SIZE 5M AUTOEXTEND ON NEXT 5M;

CREATE TABLE tab
( 
    c1 INT, 
    c2 INT
)
PARTITION BY RANGE(c1)
( 
    PARTITION p1 VALUES LESS THAN (10),
    PARTITION p2 VALUES LESS THAN (20),
    PARTITION p3 VALUES LESS THAN (30)
);

-- 创建全局分区索引
CREATE INDEX pti ON tab(c2)
GLOBAL PARTITION BY RANGE(c2)
( 
    PARTITION p_10 VALUES LESS THAN (10),
    PARTITION p_20 VALUES LESS THAN (20),
    PARTITION p_others VALUES LESS THAN (maxvalue)
);


--方法一,这个方法适用于截断拥有大量数据的分区表:
ALTER TABLE tab TRUNCATE PARTITION p1;
ALTER INDEX pti REBUILD;

--方法二,这个方法适用于小表或者大表但是删除的分区占有少量的数据:
DELETE FROM tab PARTITION (p2);
ALTER TABLE tab TRUNCATE PARTITION p2;

--方法三:
ALTER TABLE tab TRUNCATE PARTITION p3
UPDATE INDEXES;


--  删除表和表空间
DROP INDEX pti;
DROP TABLE tab CASCADE;
DROP TABLESPACE ts1;
DROP TABLESPACE ts2;

示例2:截断一级子分区表

DROP TABLE tab;

-- 创建分区表
CREATE TABLE tab 
(
    id NUMERIC, 
    time_id DATE
)
PARTITION BY RANGE (time_id)
INTERVAL(INTERVAL '1' MONTH)
(
    PARTITION p1 VALUES LESS THAN ('2007-05-01'),
    PARTITION p2 VALUES LESS THAN ('2007-06-01')
);

ALTER TABLE tab TRUNCATE PARTITION p1;

--  删除表
DROP TABLE tab CASCADE;

截断二级子分区表 使用ALTER TABLE … TRUNCATE SUBPARTITION语句截断二级子分区表。相应的局部索引也被截断。

示例3:截断二级子分区表

--  清理环境
DROP TABLE tab;
-- 创建分区表
CREATE TABLE tab 
(
    c1 DATE, 
    c2 VARCHAR(2)
)
PARTITION BY RANGE (c1)
SUBPARTITION BY LIST (c2)
(
    PARTITION p1 VALUES LESS THAN ('2011-03-01')
    (
        SUBPARTITION p1_sub1 VALUES ('A1', 'A2'),
        SUBPARTITION p1_sub2 VALUES ('B1', 'B2', 'B3')
    ),
    PARTITION p2 VALUES LESS THAN ('2011-05-01')
);

ALTER TABLE tab TRUNCATE SUBPARTITION p1_sub2;

--  删除表
DROP TABLE tab CASCADE;