alter table ... split partition 是唯一方式,其“快速”取决于是否规避边界越界、p_default含数据、全局索引未显式维护三类阻塞点;拆分点须在原分区左闭右开区间内,含数据的p_default需先归档再拆,全局索引必须显式加update global indexes,且操作全程锁表。

ALTER TABLE ... SPLIT PARTITION 是唯一可用方式,但“快速”不取决于命令本身,而取决于你是否绕开了三类典型阻塞点:边界越界、p_default 含数据、全局索引未显式维护。
拆分点必须严格落在原分区上下界之间
ORA-14080 不是语法错误,而是边界校验失败。Oracle 会检查 AT 值是否在被拆分区的合法区间内(左闭右开),这个区间由前一分区上界和本分区上界共同决定。
- 比如
p_2022定义为VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD')),且前一分区p_2021上界是2022-01-01,那么它的实际覆盖范围就是[2022-01-01, 2023-01-01) - 只允许选这个开区间内的值,例如
TO_DATE('2022-07-01', 'YYYY-MM-DD') -
TO_DATE('2021-12-01', ...)❌(低于下界)、TO_DATE('2023-01-01', ...)❌(等于上界)都会报错
含数据的 DEFAULT 分区不能直接拆
p_default 看似兜底,但一旦有数据,SPLIT PARTITION 就会触发全量数据重分布——锁表、慢、易引发 enq:TM-contention。
- 先确认是否有数据:
SELECT COUNT(*) FROM your_table PARTITION(p_default); - 若结果 > 0:
- 不要硬拆,优先归档旧数据(如
INSERT INTO archive_table SELECT * FROM your_table PARTITION(p_default) WHERE ...) - 或用
UPDATE ... WHERE ...迁移部分数据出该分区后再拆
- 不要硬拆,优先归档旧数据(如
- 拆分语句中
INTO子句的顺序不能反:INTO (PARTITION p_2023, PARTITION p_default)—— 后者必须仍是p_default,否则新插入的数据会进错分区
全局索引必须显式加 UPDATE GLOBAL INDEXES
只要表上有全局唯一索引(主键、唯一约束等),默认SPLIT PARTITION 会让这些索引变成 UNUSABLE,后续所有 DML 都会失败。
- 必须写全:
UPDATE GLOBAL INDEXES(漏掉GLOBAL就只更新本地索引) -
UPDATE GLOBAL INDEXES在 Oracle 11g 支持,但会延长执行时间;若索引极大且业务可容忍短时不可写,可考虑先ALTER INDEX ... UNUSABLE再重建 - 本地索引不受影响,无需额外操作
锁表影响比预想中更严重
SPLIT PARTITION 持有 AccessExclusiveLock,整个表在执行期间无法进行任何 INSERT/UPDATE/DELETE,连 SELECT FOR UPDATE 都会被阻塞。
- 千万别在业务高峰执行
- 如果表数据量极大(比如单分区超 50GB),即使边界和索引都正确,执行时间也可能长达数十分钟——建议提前在备库验证耗时
- 没有“后台异步拆分”或“在线无锁拆分”这种捷径,所有拆分都是同步阻塞操作
真正卡住的从来不是语法,而是你没查 p_default 有没有数据、没算清上下界、没加 UPDATE GLOBAL INDEXES。这三个动作漏一个,就不是“慢”,而是根本跑不通。











