本地索引适合查询条件频繁包含分区键且目标为单个或连续几个分区的场景,能自动分区裁剪、降低i/o与cpu开销;适用于按时间范围查询、定期截断旧分区、单分区重建索引及位图索引等。

本地索引适合什么查询场景
当查询条件里频繁包含表的分区键(比如 sale_date、created),且目标是单个或连续几个分区时,本地索引能自动完成分区裁剪,只扫描相关索引分区,I/O 和 CPU 开销显著更低。
常见适用情况包括:
- 按月/年查询销售数据,表按
sale_date范围分区,索引也建在该列上并声明LOCAL - ETL 任务中定期截断旧分区(如
ALTER TABLE sales TRUNCATE PARTITION p_202501),本地索引对应分区自动清空,无需额外维护 - 需要对单个分区重建索引(如修复损坏或优化统计信息):
ALTER INDEX idx_sales_local REBUILD PARTITION p_202501 - 使用位图索引——Oracle 强制要求必须是本地索引
注意:本地索引无法跨分区保证唯一性。如果要用它支持 UNIQUE 约束,约束字段必须包含分区键,例如 UNIQUE (sale_id, sale_date),否则会报错 ORA-14035: invalid partitioning of index。
全局索引适合什么查询场景
当你需要按非分区键字段高频查询(比如客户 ID、订单号),且结果必然跨多个表分区时,全局索引才是合理选择。它把所有表分区的数据“扁平化”组织进一个逻辑索引,按自己的规则(范围或哈希)再切分。
典型用例有:
- 通过
customer_id快速定位某客户全部历史订单,而订单表按order_date分区 - 需要全表唯一约束(如
UNIQUE(customer_id)),且不希望约束字段绑定分区键 - 高并发 OLTP 场景下,用哈希分区全局索引分散写热点(避免单一分区索引段争用)
但代价明确:任何表分区 DDL(TRUNCATE PARTITION、DROP PARTITION、EXCHANGE PARTITION)都会让全局索引整体失效,必须执行 ALTER INDEX ... REBUILD 或先置为 UNUSABLE 再重建——这期间索引不可用,且重建耗时随数据量线性增长。
本地索引前缀 vs 非前缀的区别
本地索引是否以分区键作为引导列,直接影响能否高效裁剪。前缀本地索引(如表按 sale_date 分区,索引定义为 CREATE INDEX ... ON sales(sale_date, product_id) LOCAL)在 WHERE sale_date = ... 条件下可精准定位分区;而非前缀索引(如 ON sales(product_id, sale_date) LOCAL)即使查询含 sale_date,也可能无法裁剪,导致扫全索引分区。
验证方式很简单:
- 执行
EXPLAIN PLAN FOR SELECT ...后查PLAN_TABLE,看OBJECT_PARTITION列是否只出现一个分区名 - 或直接查
dba_indexes的partitioning_type和prefix_length字段
非前缀本地索引不是不能用,而是容易误判性能收益——它看起来“本地”,实际可能失去分区优势。
创建时最容易忽略的兼容性细节
Oracle 对索引分区类型有硬性限制,不是所有组合都合法:
- 全局索引只支持
RANGE或HASH分区,不支持LIST或COMPOSITE全局分区;想用列表分区索引,只能选本地 -
BITMAP索引强制要求本地,建全局位图索引会直接报错ORA-25154 - Oracle 12c 及以后版本允许全局索引带
UPDATE GLOBAL INDEXES子句(如ALTER TABLE ... DROP PARTITION ... UPDATE GLOBAL INDEXES),但前提是索引本身支持该语法,且会延长 DDL 执行时间 - 表空间分配易被忽视:本地索引各分区可指定不同表空间(利于 I/O 均衡),而全局索引所有分区默认继承主索引段的表空间,需显式用
PARTITION ... TABLESPACE控制
真正麻烦的不是选错类型,而是上线后才发现某个关键查询始终走不了索引——往往卡在分区键未出现在查询条件、索引非前缀、或全局索引因分区维护失效却没及时重建这几个点上。











