ALTER TABLE…TRUNCATE PARTITION

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

语法介绍

ALTER TABLE table_name TRUNCATE PARTITION partition_name
  [{DROP|REUSE} STORAGE]

参数说明

参数名称

参数要求

参数说明

参数示例

table_name

必填

要清空分区的目标分区表的名称。

sales_records

partition_name

必填

要清空的分区的名称。

p_2023_q1

{DROP|REUSE} STORAGE 

选填

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

DROP STORAGE/

REUSE STORAGE

注意事项

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

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

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

  • 如果表上定义了ON TRUNCATE 触发器,该操作会触发它们。请确保了解这些触发器可能执行的业务逻辑,避免意外的连锁反应。

使用示例

本示例演示如何清空一个销售记录表中的历史季度分区。此操作常用于数据生命周期管理,即删除旧数据但保留分区结构,以便将来加载同一时期的新数据。

环境准备

本步骤将创建一个按销售日期进行范围分区的表 sales_records,并创建两个分区p_2023_q1p_2023_q2分别用于保存一季度和二季度的数据。

-- 创建分区表
CREATE TABLE sales_records (
    sale_id    INT NOT NULL,
    product_id INT NOT NULL,
    sale_date  DATE NOT NULL
)
PARTITION BY RANGE (sale_date) (
    PARTITION p_2023_q1 VALUES LESS THAN (TO_DATE('2023-04-01', 'YYYY-MM-DD')),
    PARTITION p_2023_q2 VALUES LESS THAN (TO_DATE('2023-07-01', 'YYYY-MM-DD'))
);

-- 插入数据
INSERT INTO sales_records VALUES (1, 101, TO_DATE('2023-01-15', 'YYYY-MM-DD'));
INSERT INTO sales_records VALUES (2, 102, TO_DATE('2023-04-20', 'YYYY-MM-DD'));
COMMIT;

前置检查

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

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

-- 检查分区结构,确认待清空的分区 p_2023_q1 存在
SELECT PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'SALES_RECORDS';

-- 检查分区数据,确认分区内存在数据
SELECT COUNT(*) FROM sales_records PARTITION (p_2023_q1);

执行操作

执行 TRUNCATE PARTITION 命令清空 p_2023_q1 分区。

ALTER TABLE sales_records TRUNCATE PARTITION p_2023_q1;

结果验证

验证分区结构被保留、数据被清空。

-- 结构验证:确认分区定义仍然存在
SELECT PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'SALES_RECORDS';
-- 查询结果中仍包含 p_2023_q1

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

清空操作会使表的统计信息过时,影响查询优化器的判断。操作完成后应立即执行 ANALYZE

ANALYZE sales; -- 更新父表的统计信息

常见问题

Q1:TRUNCATE PARTITION 和 DROP PARTITION 有什么区别?
TRUNCATE PARTITION 仅清空分区内的数据但保留分区定义,而 DROP PARTITION 会将分区定义和数据一并删除。

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

Q3:执行此命令为什么提示 RA-02149: specified partition does not exist
分区名不存在或大小写不匹配。分区名大小写敏感,请先通过查询确认分区名称,或使用双引号精确引用。

Q4:执行此命令为什么提示 ORA-01031: insufficient privileges
这是因为执行该命令的用户不具备目标表的 ALTER 权限,需要联系数据库管理员授予相应权限。

Q5:执行此命令为什么提示ERROR: cannot truncate partition of table because it has global indexes

有全局索引时,执行 TRUNCATE PARTITION 会失败。全局索引跨所有分区维护唯一性和查询路径,TRUNCATE 无法在不破坏索引一致性的前提下快速清理索引条目。

相关语句