ALTER TABLE…TRUNCATE SUBPARTITION

ALTER TABLE ... TRUNCATE SUBPARTITION 用于清空复合分区表中指定子分区内的全部数据,此操作会永久移除数据但保留子分区结构,执行前需确认数据不再需要或已备份。

语法介绍

ALTER TABLE table_name 
  TRUNCATE SUBPARTITION subpartition_name 
  [{DROP|REUSE} STORAGE]

参数说明

参数名称

参数要求

参数说明

参数示例

table_name

必填

目标复合分区表的名称。

customer_data

subpartition_name

必填

要清空的子分区的名称。

p_2022_asia

{DROP|REUSE} STORAGE

选填

子句仅为兼容 Oracle 语法而存在,会被解析但实际忽略,不影响存储行为。

DROP STORAGE/

REUSE STORAGE

注意事项

  • 执行此命令的用户需是该表的所有者,或拥有对该表的 ALTER 权限。

  • 该操作会获取AccessExclusiveLock(表级排他锁),阻塞该表的所有 DML 和大部分 DDL 操作。建议在业务低峰期执行,并预留足够的时间窗口。

  • TRUNCATE SUBPARTITION是一项DDL操作,会隐式提交当前事务,一旦执行,被删除的数据无法通过 ROLLBACK 回滚。请在操作前完成数据备份。

  • TRUNCATE SUBPARTITION是元数据操作+文件删除,即使亿级数据也可秒级完成,I/O 和CPU/内存开销极低。

使用示例

本示例演示如何在一个按注册年份(RANGE)和用户所在地区(LIST)进行复合分区的客户表中,清空2022年度亚洲地区的用户数据子分区。

环境准备

本步骤将创建一个复合分区表 customer_data,该表按注册年份进行范围分区(p_2022),再按用户所在地区进行列表子分区(p_2022_asia 和 p_2022_europe),并向这两个子分区插入测试数据。

-- 创建复合分区表
CREATE TABLE customer_data (
    customer_id  INT NOT NULL,
    region       VARCHAR2(10),
    reg_date     DATE
)
PARTITION BY RANGE (reg_date)
SUBPARTITION BY LIST (region)
(
    PARTITION p_2022 VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD'))
    (
        SUBPARTITION p_2022_asia    VALUES ('Asia'),
        SUBPARTITION p_2022_europe  VALUES ('Europe')
    )
);

-- 插入数据
INSERT INTO customer_data VALUES (101, 'Asia', TO_DATE('2022-06-10', 'YYYY-MM-DD'));
INSERT INTO customer_data VALUES (102, 'Europe', TO_DATE('2022-07-20', 'YYYY-MM-DD'));

前置检查

在执行清空操作前,确认数据已备份,并检查目标子分区的结构和数据。

-- 重要:执行清空操作前,请确保已对相关数据进行备份。

-- 检查子分区结构,确认待清空的子分区 p_2022_asia 存在
SELECT SUBPARTITION_NAME FROM USER_TAB_SUBPARTITIONS WHERE TABLE_NAME = 'CUSTOMER_DATA';

-- 检查子分区数据,确认分区内存在数据
SELECT COUNT(*) FROM customer_data SUBPARTITION (p_2022_asia);

执行操作

执行 TRUNCATE SUBPARTITION 命令清空 p_2022_asia 子分区。

ALTER TABLE customer_data TRUNCATE SUBPARTITION p_2022_asia;

结果验证

验证子分区结构被保留,且数据已被清空。

-- 结构验证:确认子分区定义仍然存在
SELECT SUBPARTITION_NAME FROM USER_TAB_SUBPARTITIONS 
WHERE TABLE_NAME = 'CUSTOMER_DATA';
-- 查询结果中应包含 p_2022_asia

-- 数据验证:确认子分区内的数据已被清空
SELECT COUNT(*) FROM customer_data SUBPARTITION (p_2022_asia);
-- 查询结果为 0

常见问题

Q1:TRUNCATE SUBPARTITION 和 DROP SUBPARTITION 有什么区别?

TRUNCATE SUBPARTITION仅清空子分区内的数据但保留其定义,而DROP SUBPARTITION 会将子分区定义和数据一并删除。

Q2:执行 TRUNCATE SUBPARTITION 后,数据可以恢复吗?

不可以,因为 TRUNCATE 是一项DDL操作,它会永久删除数据且默认不记录在事务日志中,无法通过常规手段回滚或闪回。

Q3:TRUNCATE SUBPARTITION 和 DELETE FROM ... SUBPARTITION 有什么区别?

TRUNCATE SUBPARTITION 是高效的DDL操作,通过释放数据块直接删除数据且无法回滚,而DELETE是逐行删除的DML操作,会记录日志、可回滚并触发删除触发器。

Q4:执行此命令为什么提示 ORA-02149:relation ... does not exist

子分区名不存在或大小写不匹配。名称大小写敏感,请先前置检查确认名称。

Q5:执行此命令为什么提示 ORA-01031: insufficient privileges

这是因为执行该命令的用户不具备目标表的 ALTER 权限,需要联系数据库管理员授予相应权限。

相关语句