23c前多级分区维护极麻烦:组合分区DDL需显式指定子分区且易使全局索引失效,缺乏IF EXISTS导致脚本需大量异常处理;23c引入IF EXISTS/NOT EXISTS、INCLUDING ROWS及SQL Domain等特性,显著简化自动化运维与分区策略可靠性。

多级分区表维护为何在23c前特别麻烦
Oracle 12c起支持组合分区(如 RANGE-LIST、RANGE-HASH),但维护操作(SPLIT、MERGE、MOVE)必须显式指定每个子分区,且全局索引容易失效;更关键的是,DDL语句不带 IF EXISTS 时,脚本重复执行直接报错中断,自动化运维脚本得层层加 EXCEPTION 捕获。DBA常为一个归档分区写十几行PL/SQL包装逻辑,就为了判断分区是否存在、索引是否可用、是否需重建。
用 IF [NOT] EXISTS 避免 DDL 执行中断
23c原生支持 IF EXISTS 和 IF NOT EXISTS 语法,对分区维护类DDL尤其实用——比如定期清理旧分区的脚本,不再需要先查 user_tab_partitions 再条件执行:
ALTER TABLE sales DROP PARTITION sales_q1 IF EXISTS;
这个语句无论 sales_q1 是否存在,都静默成功;同理,新建子分区时:
ALTER TABLE orders SPLIT PARTITION ord_2025_q1 AT (DATE '2025-04-01') INTO (PARTITION ord_2025_q1_a, PARTITION ord_2025_q1_b) IF NOT EXISTS;
- 旧版本必须用 PL/SQL +
EXECUTE IMMEDIATE+ 异常处理才能模拟该行为 -
IF NOT EXISTS对子分区名也生效,避免因误操作重复拆分导致ORA-14074错误 - 注意:该语法仅适用于 DDL,不适用于DML;且不支持嵌套使用(如
IF EXISTS ... ELSE ...)
利用自动列表分区 + 维护过滤减少人工干预
23c延续并强化了12.2引入的自动列表分区能力,配合 INCLUDING ROWS 过滤语法,能大幅降低多级分区中“局部数据迁移”的复杂度。例如一张按 (region, status) 多列列表分区的订单表,某次只需把 region = 'EU' 下所有 status = 'CANCELLED' 的记录移出当前分区:
ALTER TABLE orders MOVE PARTITION eu_active INCLUDING ROWS WHERE status = 'CANCELLED';
这条命令会自动创建新分区(如果未定义)、只搬符合条件的行、保留其余行不动——而旧版本必须先 CREATE TABLE ... AS SELECT 导出再 INSERT /*+ APPEND */ 回填,中间还涉及锁和日志爆炸风险。
- 多级分区下,
INCLUDING ROWS作用于最内层子分区,父分区定义无需调整 - 执行后原分区的高水位线(HWM)会下降,但不会自动释放空间;需后续
ALTER TABLE ... SHRINK SPACE - 该操作仍会生成redo,但比全量MOVE小得多;若想零日志,需确保表启用NOLOGGING且在ARCHIVELOG模式外执行(不推荐生产)
布尔类型与SQL Domains让分区策略元数据更可靠
分区键本身若含业务语义(如 is_archived BOOLEAN、data_source DOMAIN),过去只能靠注释或外部文档约定,23c的 BOOLEAN 类型和 SQL Domain 可将其固化为数据库对象:
CREATE DOMAIN data_source AS VARCHAR2(20) CHECK (VALUE IN ('WEB', 'MOBILE', 'API')) DEFAULT 'WEB';<br>CREATE TABLE logs (id NUMBER, src data_source, ts DATE) PARTITION BY LIST (src);
这样做的实际好处是:
- 插入非法值(如
'FTP')直接报ORA-02290,无需应用层校验 - 分区裁剪更稳定:优化器知道
src只有三个确定值,对WHERE src = 'WEB'能精准定位单一分区 - 配合布尔字段做二级分区键时(如
PARTITION BY LIST (is_archived, region)),TRUE/FALSE比'Y'/'N'更不易歧义,也避免字符集比较问题
真正棘手的不是语法怎么写,而是分区键字段的取值分布是否真实收敛——哪怕用了23c所有新特性,若 region 字段80%值为 'UNKNOWN',分区裁剪照样失效。这点永远比语法细节重要。


















