Oracle INTERVAL分区表建表必须指定START WITH,否则报ORA-14751;仅支持单个DATE/TIMESTAMP/NUMBER列作分区键;自动分区在INSERT严格大于当前最高上界时触发;查询需字面量条件才能有效剪枝;删除旧分区只能DROP PARTITION,不可TRUNCATE且末尾分区禁止删除。
Oracle INTERVAL 分区表建表时必须指定 START WITH
不写 start with 会报错 ora-14751: invalid data type for partitioning column,哪怕列类型是 date 或 timestamp。oracle 要求明确首个分区的边界起点,否则无法推导后续间隔。
实操建议:
-
INTERVAL只支持单个DATE、TIMESTAMP或NUMBER列,且该列必须是分区键(不能是组合键的一部分) - 用
START WITH DATE '2024-01-01'比用SYSDATE更稳妥——后者在 DDL 执行瞬间取值,可能因时区或 NLS 设置导致隐式转换失败 - 若想按月分区,
INTERVAL NUMTOYMINTERVAL(1, 'MONTH')是唯一合法写法;写成'1 MONTH'或INTERVAL '1' MONTH全部报错
INSERT 触发自动分区生成的边界条件
新分区不会在建表时立刻生成,而是在第一条落在“当前最大分区上限之外”的 INSERT 执行时才创建。但这个“之外”有严格定义:必须严格大于已有最高分区的 VALUES LESS THAN 上界。
常见错误现象:
- 插入
DATE '2024-02-15',但当前最大分区是VALUES LESS THAN (DATE '2024-02-01')→ 自动建分区 ✅ - 插入同一天的另一条记录,但上界是
DATE '2024-02-15'→ 不触发新建 ❌(等于上界不算“之外”) - 插入
NULL值到分区键列 → 直接报错ORA-14400: inserted partition key does not map to any partition
性能影响:首次触发分区生成会带来轻微 DDL 开销(约几十毫秒),高并发写入时可能成为争用点,建议预热写入最早几条未来日期数据。
查询时没走分区剪枝?检查 WHERE 条件是否可推导
Oracle 对 INTERVAL 分区的剪枝依赖优化器能否静态确定过滤条件落在哪个(些)分区。一旦表达式不可推导,就会全分区扫描。
典型失效场景:
- 用
WHERE dt_column > TRUNC(SYSDATE)→ 失效(TRUNC阻断常量传播) - 用
WHERE dt_column BETWEEN :bind1 AND :bind2→ 若绑定变量未传值或为NULL,剪枝失效 - 分区键列参与函数,如
WHERE TO_CHAR(dt_column, 'YYYYMM') = '202402'→ 必然全扫
正确写法示例:WHERE dt_column >= DATE '2024-02-01' AND dt_column ,确保字面量且无函数包裹。
删除旧分区只能用 DROP PARTITION,不能用 TRUNCATE
INTERVAL 分区表不支持 TRUNCATE PARTITION,语法直接报错 ORA-14758: Last partition in the range section cannot be dropped。这是因为 Oracle 把最右端分区视为“模板锚点”,删了就无法继续推导新分区。
安全操作路径:
- 先用
SELECT partition_name, high_value FROM user_tab_partitions WHERE table_name = 'TBL_LOG'查出待删分区名 - 执行
ALTER TABLE tbl_log DROP PARTITION p202312;(注意:不能删掉系统自动生成的最后一个分区) - 若误删了末尾分区,需重建表——没有在线修复手段
容易被忽略的一点:DROP PARTITION 是 DDL,会隐式提交,且无法回滚。生产环境务必先在测试库验证分区名和范围。










