加UPDATE GLOBAL INDEXES是防止全局索引失效的必要操作,否则DROP/EXCHANGE PARTITION后索引立即变为UNUSABLE,导致后续INSERT报ORA-01502;其原理是Oracle为保障数据安全,默认不维护跨分区的全局索引一致性。
加 update global indexes 子句不是“可选优化”,而是防止全局索引静默失效的必要动作——不加,drop partition 或 exchange partition 一执行完,索引就变 unusable,后续 insert 直接报 ora-01502。
为什么 DROP PARTITION 不加 UPDATE GLOBAL INDEXES 就失效
Oracle 默认不维护全局索引,是因为全局索引跨分区,删一个分区后,索引里还存着指向已删除数据块的条目。它不敢假设一致性,直接停用整个索引(状态变 UNUSABLE),而不是尝试局部清理。这不是 bug,是强制保障数据安全的设计。
本地索引(LOCAL)不会这样:每个分区索引段独立,删分区等于删掉对应索引段,其余不受影响。
-
DROP PARTITION本身不清理全局索引内容,只删表数据段 - 失效是立即发生的,且无日志提示,容易被忽略
- 哪怕索引当前是
VALID,只要 DDL 没带该子句,执行完就变UNUSABLE
UPDATE GLOBAL INDEXES 能做什么、不能做什么
它是在分区 DDL 执行过程中,同步扫描并修正全局索引中所有指向被删/被换分区的条目,等价于隐式触发一次 ALTER INDEX ... REBUILD。但它只对“尚未失效”的索引起效。
- 对
GLOBAL索引:重建整个索引段,耗时与索引大小正相关 - 对
LOCAL索引:不生效(UPDATE GLOBAL INDEXES对本地索引无意义) - 已处于
UNUSABLE状态的索引:再补这个子句也没用,DDL 会失败或忽略 - 不支持
TRUNCATE PARTITION场景,仅适用于DROP/EXCHANGE/SPLIT/MERGE
加了还是报 ORA-01502?先查这三件事
常见原因是索引在 DDL 前已有残留的 UNUSABLE 分区,或 DDL 执行中途被中断(比如被 kill、实例崩溃),导致索引卡在中间态。
- 执行前务必查:
SELECT index_name, status, funcidx_status FROM user_indexes WHERE table_name = 'YOUR_TABLE' - 如果看到
UNUSABLE,别硬上 DDL,先ALTER INDEX idx_name REBUILD - 若 DDL 带
UPDATE GLOBAL INDEXES后仍失败,索引大概率已残留在UNUSABLE状态,必须显式重建,不能重试原语句 - 注意:
REBUILD默认NOLOGGING,如需归档同步,记得加LOGGING
大表慎用 UPDATE GLOBAL INDEXES 的真实代价
它看起来“在线”,但实际锁表、耗资源、拖时间——不是所有业务都能扛住。
- 锁粒度是整张表,期间所有
INSERT/UPDATE/DELETE都会被阻塞 - 性能开销是普通
DROP PARTITION的 3–10 倍,尤其当全局索引键值分散、DML 并发高时 - 需要额外临时空间,约为索引当前大小的 1.2–1.5 倍
- 真正适合的场景只有:小分区 + 少量全局索引 + 业务不可中断
如果表是 TB 级、有 5 个以上全局索引、SLA 要求严,宁可停写几分钟,走 UNUSABLE + REBUILD 两步法,也别赌 UPDATE GLOBAL INDEXES 能稳过。


















