选本地索引还是全局索引取决于查询条件是否含分区键、分区ddl频率及是否需非分区键唯一约束:带分区键优先local,点查非分区键必须global,高频分区变更宜local,全表唯一性必须global,混合场景需二者并用。

选本地索引还是全局索引,不取决于“哪个更好”,而取决于你查什么、怎么改分区、要不要唯一约束——三者缺一不可。
WHERE条件里带不带分区键
这是最直接的判断依据。如果查询几乎总是带上分区键(比如 WHERE create_time BETWEEN '2026-01-01' AND '2026-03-31' 且表按时间分区),本地索引能自动完成分区裁剪,只扫对应几个索引分区;否则优化器可能放弃走本地索引,转而全表扫描或合并多个索引分区,开销陡增。
- 带分区键 → 优先考虑
LOCAL索引 - 不带分区键(如
WHERE order_no = 'ORD123456')→ 必须用GLOBAL索引,否则查不到或极慢 - 混合场景(有时带、有时不带)→ 得拆成两个索引:一个
LOCAL覆盖范围查询,一个GLOBAL支撑点查
分区 DDL 操作频率高不高
本地索引对 DROP PARTITION、TRUNCATE PARTITION、EXCHANGE PARTITION 是透明的:操作后索引分区自动失效并重建,不影响其他分区;全局索引则会整体进入 UNUSABLE 状态,必须显式加 UPDATE GLOBAL INDEXES 子句,否则后续查询直接退化为全表扫描。
- 高频归档/清理旧分区(如每日删一个月前数据)→ 只能用
LOCAL - 分区结构稳定、极少变更(如年分区表,每年只加一次)→
GLOBAL可接受 - 误删分区后发现查询变慢,先查
dba_indexes.status,不是VALID就得修复
需不需要非分区键上的唯一约束
本地索引只能保证“单个分区内部”唯一,无法防止跨分区重复。比如按 region 分区的用户表,在 mobile 上建本地索引,同一手机号可能在不同 region 分区里各存一条。
- 要求全表唯一(如手机号、订单号)→ 必须用
GLOBAL UNIQUE索引 - 业务允许分区级唯一(如每个 region 内 mobile 不重复)→
LOCAL UNIQUE可行,但约束定义里必须包含分区键 - Oracle 会拒绝创建不包含分区键的
LOCAL UNIQUE索引,报错ORA-14035
写入性能和索引维护成本
每次 INSERT 或 UPDATE 都要更新索引。本地索引只需定位到本分区对应的索引段;全局索引则要全局 B-tree 定位,锁粒度更粗,高峰写入时容易卡住。
- 高并发写入 + 分区键天然分散(如按时间插入)→
LOCAL压力小得多 - 建全局索引时别在业务高峰期跑
CREATE INDEX,否则可能触发ORA-00054或长时间阻塞 - 想加速建索引?Oracle 可加
PARTITION和PARALLEL,PG 则必须用CONCURRENTLY,但都逃不开全表扫描
真正难的不是选本地还是全局,而是当业务同时需要分区裁剪、跨分区点查、全表唯一性、低维护成本时——这时候没有银弹,只能靠组合策略:主键走全局唯一索引,时间范围查询走本地索引,再配合物化视图或应用层缓存补漏。











