按天自动分区必须用numtodsinterval(1, 'day'),因oracle仅支持numtoyminterval(年/月)和numtodsinterval(日/时/分/秒);误写为numtoyminterval(1,'day')等会报ora-00907或ora-30075错误。
按天自动分区必须用 numtodsinterval(1, 'day')
oracle 的 interval 分区只支持两种时间粒度函数:numtoyminterval(年/月)和 numtodsinterval(日/时/分/秒)。按天分区只能用后者,写成 numtoyminterval(1, 'day') 会直接报错 ora-00907: missing right parenthesis 或 ora-30075: interval literal must be a day to second interval。
常见错误是把年月的写法套用到天——比如误写 NUMTOYMINTERVAL(1, 'day'),或漏掉括号、大小写不一致(如 numtodsinerval)。
-
NUMTODSINTERVAL(1, 'day')正确,生成每天一个新分区 -
NUMTODSINTERVAL(24, 'hour')等效但不推荐,语义不清且易出错 -
NUMTODSINTERVAL(1, 'DAY')在部分 Oracle 版本中会失败,建议全小写
CREATE TABLE 语句里必须带初始分区 + LESS THAN 上界
interval 分区表不能只写 INTERVAL 就完事。Oracle 要求至少定义一个“基础”范围分区,用 VALUES LESS THAN 明确划出第一个分区的上限,后续分区才按间隔自动衍生。
比如你想从 2026-05-01 开始按天分区,就得写:
CREATE TABLE log_daily ( id NUMBER, event_time DATE ) PARTITION BY RANGE (event_time) INTERVAL (NUMTODSINTERVAL(1, 'day')) ( PARTITION p_init VALUES LESS THAN (DATE '2026-05-01') );
注意:DATE '2026-05-01' 是标准日期字面量,比 TO_DATE('2026-05-01', 'yyyy-mm-dd') 更简洁安全;若用 TO_DATE,格式掩码必须严格匹配,否则插入数据时可能因 NLS 设置不同导致分区定位失败。
插入数据后分区不会立刻可见,查 USER_TAB_PARTITIONS 才能确认
刚建完表时,SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'LOG_DAILY' 只能看到 P_INIT。只有当插入的数据时间戳 ≥ 2026-05-01,Oracle 才真正创建第一个自动分区(名字类似 SYS_P123),并持续为后续日期创建新分区。
验证方法:
- 执行
INSERT INTO log_daily VALUES (1, DATE '2026-05-01'); - 再查
USER_TAB_PARTITIONS,应出现至少两个分区:原始P_INIT和一个SYS_Pxxx - 查
SELECT partition_name, high_value FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'LOG_DAILY',可看到每个分区的HIGH_VALUE实际值(是表达式,非具体日期)
别依赖 DBA_SEGMENTS 或表空间使用率来判断分区是否生成——段分配可能延迟,而分区元数据在 USER_TAB_PARTITIONS 中最准。
自动分区对表空间和索引有隐含要求
interval 分区表默认把新分区建在原表所在表空间。如果业务持续写入,一年会产生 365 个分区,单表空间可能撑爆。生产环境务必提前指定默认表空间,或配合 ALTER TABLE ... MODIFY DEFAULT ATTRIBUTES 动态切换:
ALTER TABLE log_daily MODIFY DEFAULT ATTRIBUTES TABLESPACE ts_2026_q2;
另外,主键或唯一索引若包含分区键(如 event_time),必须建为 LOCAL 索引;若建了全局索引,每次新增分区都会触发索引维护,严重拖慢 DML 性能。建表后立即检查:
SELECT index_name, index_type, status FROM USER_INDEXES WHERE table_name = 'LOG_DAILY';
看到 INDEX_TYPE = 'NORMAL' 就要警惕——大概率是全局索引,应重建为 LOCAL。
自动分区看着省事,但分区名不可控(全是 SYS_Pxxx)、无法预分配未来分区、且 HIGH_VALUE 是动态计算的表达式——这些特性会让归档、跨分区查询、权限控制变得微妙。真要长期用,得搭配定期 EXCHANGE PARTITION 和 DROP PARTITION 的运维脚本,不能只靠“自动”二字躺平。











