GLOBAL和LOCAL索引无绝对优劣,需匹配查询模式与维护场景:含分区键的范围查询优先LOCAL索引,不含分区键的唯一性或点查选GLOBAL索引,混合场景宜组合使用两类索引。
GLOBAL 和 LOCAL 索引没有绝对“更好”,只有更匹配查询模式和维护场景。选错类型会导致全分区扫描、索引失效或维护停机,实际效果可能比没建索引还差。
WHERE 条件含分区键时优先用局部索引
当查询谓词中稳定包含表的分区键(比如 submittime 或 datatime),且常按时间范围过滤时,local 索引能天然支持分区剪裁,执行计划里只访问目标分区对应的索引段。
常见错误现象:建了 LOCAL 索引但查询不带分区键,例如对按 datatime 分区的表只查 WHERE partno = 'A123',Oracle 会扫所有索引分区,性能反不如非分区索引。
- 前缀局部索引(如
CREATE INDEX idx ON t(datatime, partno) LOCAL)剪裁最可靠 - 非前缀局部索引(如
CREATE INDEX idx ON t(partno) LOCAL)无法剪裁,必须全扫,慎用 - 局部索引在
TRUNCATE PARTITION后仍有效,无需重建,可用性高
WHERE 条件不含分区键但需唯一性或高频点查时选全局索引
业务主键或唯一约束字段与分区键无关(比如 orderno、user_id),又要求全表唯一,只能用 GLOBAL 索引——LOCAL 索引做不到跨分区唯一校验。
典型场景:OLTP 中按订单号查单条记录,SQL 常为 WHERE orderno = 123456789,此时 GLOBAL 非分区索引(或按 orderno 分区的全局索引)可直接定位到单个索引块,避免扫全表所有分区。
-
GLOBAL索引必须是前缀型:分区键必须是索引列的最左前缀,否则建索引报ORA-14038 - 对分区表做
TRUNCATE PARTITION或MOVE PARTITION时,GLOBAL索引默认失效,需加UPDATE GLOBAL INDEXES子句才保持可用(代价是延长 DDL 时间) - 全局非分区索引(即不带
PARTITION BY的GLOBAL)在 Oracle 11g 中仍是主流选择,简单稳定
混合查询模式下别硬扛,考虑组合策略
一张表既要按时间范围查(WHERE datatime BETWEEN ...),又要按业务码点查(WHERE partno = ...),单一种类索引很难兼顾。
常见踩坑:试图用一个 LOCAL 索引覆盖两类查询,结果非分区键查询变全分区扫描;或强行上 GLOBAL 索引,导致时间范围查询失去剪裁能力。
- 务实做法:建两个索引——一个
LOCAL索引(datatime, ...)服务范围查询,一个GLOBAL索引(partno, ...)服务点查 - 注意空间和维护开销:每个索引都增加 INSERT/UPDATE 成本,尤其批量导入时
- 位图索引只能是
LOCAL,且仅适用于低基数列+数据仓库只读场景,OLTP 中禁用
Oracle 11g 的兼容性细节不能忽略
Oracle 11g 对全局索引的支持已较成熟,但仍有关键限制:
- 全局索引不支持
LIST分区方式,只支持RANGE和HASH(HASH自 10g 起支持) -
UPDATE GLOBAL INDEXES在 11g 中可用,但若索引过大,DDL 可能卡住数分钟,线上操作需评估窗口 -
LOCAL索引无法用于主键约束,除非主键包含分区键;而GLOBAL索引可以——这是建表时就该决定的事
真正容易被忽略的点在于:索引类型一旦选定,后期变更成本极高。建表初期就要根据核心查询 SQL 的 WHERE 模式、唯一性要求、以及预计的分区维护频率,同步敲定索引策略,而不是等慢查询出现后再补救。


















