本地索引必须与分区键对齐,因其本质是每个分区独立索引,若索引列不以分区键或其前缀开头,则分区裁剪失效、dml报错;对齐要求索引列须以分区键开头,唯一索引下分区键必须为第一列。
本地索引为什么必须和分区键对齐
因为 Oracle 的 LOCAL 索引本质是“每个分区一张独立索引”,它不跨分区维护 B-tree 结构。一旦索引定义的列不包含分区键(或前缀),Oracle 就无法保证查询时只扫描目标分区的索引段——这会让分区裁剪失效,性能退化成全局索引水平。
常见错误现象:EXPLAIN PLAN 显示 INDEX RANGE SCAN 但实际执行时 Partition Start/Stop 是 KEY 或 ALL,说明没对齐;或者 DML 操作报错 ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITION,根源常是本地索引列顺序/类型与分区键不一致。
- 对齐要求:索引列必须以分区键(或其前缀)开头,比如按
order_date范围分区,则CREATE INDEX idx ON t(order_date, status)合法,CREATE INDEX idx ON t(status, order_date)不合法 - 唯一约束场景下,分区键必须是唯一索引的第一列,否则建索引会失败:
ORA-14039: partitioning columns must form a prefix of the index key - 如果表用的是列表/哈希分区,同样适用该规则,只是分区键语义不同,对齐逻辑不变
分区操作后本地索引状态自动更新的边界
本地索引的“自动维护”其实很有限:只有 ALTER TABLE ... SPLIT/MERGE/EXCHANGE/DROP PARTITION 这几类操作会触发对应索引分区的自动重建或继承,其它操作如 TRUNCATE PARTITION 或直接删数据,索引状态不受影响。
容易踩的坑:TRUNCATE PARTITION 后索引分区仍是 USABLE,但里面已空;而 DROP PARTITION 会连带删掉对应本地索引分区,不会留 orphaned segment——这点和全局索引完全不同。
-
SPLIT PARTITION:原索引分区自动拆成两个,新分区索引状态为USABLE,无需REBUILD -
EXCHANGE PARTITION:交换表若无索引,或索引结构不匹配,会报错;交换后本地索引分区状态继承源表对应分区的状态 -
MOVE PARTITION不触发本地索引自动维护,对应索引分区会变成UNUSABLE,必须手动ALTER INDEX ... REBUILD PARTITION
什么时候必须手动 rebuild 本地索引分区
本地索引不是“永久可用”的。只要底层分区数据发生物理移动(比如 MOVE、SHRINK SPACE、FLASHBACK TABLE 到 SCN)、或经历异常中断(如 SPLIT 失败回滚),对应索引分区就可能变为 UNUSABLE,且不会自动恢复。
典型错误现象:SELECT 报 ORA-01502: index 'X' or partition of such index is in unusable state;或者执行计划里出现 FULL TABLE SCAN 却预期走索引。
- 检查方式:
SELECT index_name, partition_name, status FROM dba_ind_partitions WHERE index_name = 'IDX_NAME' - 单分区重建:
ALTER INDEX idx_name REBUILD PARTITION p2023q1,比全索引重建快得多 - 批量重建可用
DBMS_PART.CLEANUP_GARBAGE_COLLECT配合脚本,但注意它不处理UNUSABLE状态,仅清理元数据残留 - 重建过程锁粒度是分区级,不影响其它分区的 DML,这是本地索引相比全局索引的关键优势
本地索引 vs 全局索引在分区维护中的真实开销差异
很多人以为本地索引“自动维护”等于“零成本”,其实不然。每次 SPLIT 或 EXCHANGE,Oracle 都要为每个新/目标分区生成新的索引段、更新数据字典、重写索引头块——这些操作在大分区上仍可观测到延迟,尤其当索引列含 LOB 或长字符串时。
性能影响点:本地索引的 DDL 并发度受限于分区数,而全局索引一次 SPLIT 可能引发整个索引树重组,耗时更长但频率低;本地索引的 DML 性能更稳定,但 DDL 维护总耗时未必更低。
- 大表做
SPLIT前建议先禁用索引监控:ALTER INDEX idx_name MONITORING USAGE关掉,避免统计干扰 - 频繁
EXCHANGE场景下,确保交换表的统计信息已收集,否则优化器可能因本地索引分区统计缺失而选错执行计划 - 如果业务允许,用
UPDATE GLOBAL INDEXES子句配合全局索引,有时比管理几十个本地索引分区更省心——前提是你能接受全局索引带来的 DDL 锁和维护窗口
对齐不是一劳永逸的事,分区键改了、索引加了列、甚至升级补丁都可能让原本可用的本地索引悄悄失效。最危险的不是报错,而是静默地不走索引。










