如何构建跨分区高效查询的全局分区索引_GLOBAL PARTITION BY RANGE?
- 内容介绍
- 相关推荐
本文共计1085个文字,预计阅读时间需要5分钟。
相关专题
GLOBAL PARTITION BY RANGE 不能直接创建在普通表上
oracle 中 global partition by range 只能用于本地索引(local)的“全局化”替代方案,但它本身不是一种独立的索引类型。你不能写 create index ... global partition by range 去直接建一个“全局范围分区索引”——语法会报错:ora-00922: missing or invalid option。
真正能用上的,是「全局分区索引」(Global Partitioned Index),它必须基于已分区的表(即表本身是 RANGE / LIST / HASH 分区),且索引的分区键可以不同于表的分区键。
- 表必须先按某种策略分区(例如按
order_dateRANGE 分区) - 全局索引需显式声明
GLOBAL PARTITION BY RANGE,并指定自己的分区列(如customer_id) - 全局索引的分区数、边界必须手动定义,不继承表的分区结构
建全局分区索引前必须确认表已分区
如果表没分区,CREATE INDEX ... GLOBAL 会失败,报错:ORA-14038: GLOBAL partitioned index must be created on a partitioned table。这不是权限或语法问题,是 Oracle 强制约束。
检查方式很简单:
SELECT partitioning_type, status FROM user_part_tables WHERE table_name = 'YOUR_TABLE';
- 返回空行 → 表未分区,得先
ALTER TABLE ... SPLIT PARTITION或重建为分区表 -
PARTITIONING_TYPE是RANGE/LIST/HASH→ 可继续 - 注意:即使表有子分区(composite),也算“已分区”,满足前提
GLOBAL PARTITION BY RANGE 的分区键必须可排序且稳定
你指定的索引分区列(比如 customer_id)会被用来划分全局索引的每个分区,它的值分布直接影响查询是否能走分区裁剪。如果选了一个高倾斜字段(如状态码 status IN (0,1)),会导致大部分数据挤在 1–2 个分区里,失去跨分区高效查询的意义。
- 推荐用主键前缀、时间戳、或业务上均匀分布的数字型字段
- 避免用
VARCHAR2长文本或含大量 NULL 的列 —— 分区边界定义困难,且MAXVALUE边界对 NULL 处理不直观 - 每个分区上限要预估:Oracle 要求所有分区键值必须落在显式定义的范围内,越界 DML 会报
ORA-14400: inserted partition key is outside specified partition
示例合法语句:
CREATE INDEX idx_global_cust ON orders(customer_id) GLOBAL PARTITION BY RANGE(customer_id) ( PARTITION p1 VALUES LESS THAN (10000), PARTITION p2 VALUES LESS THAN (20000), PARTITION pmax VALUES LESS THAN (MAXVALUE) );
全局分区索引维护成本高,DML 易阻塞
和本地索引不同,全局分区索引的任意分区都可能被单条 DML 影响(比如更新 customer_id)。这意味着:表的任何分区发生 UPDATE 或 DELETE,只要涉及索引键变更,就可能触发跨分区锁,甚至导致整个索引不可用。
- 表做
DROP PARTITION或TRUNCATE PARTITION时,全局索引会 INVALID,必须加UPDATE GLOBAL INDEXES子句,否则操作失败 - 批量插入若集中在某几个
customer_id段,会争抢同一索引分区的 latch,出现enq: TX - index contention - 重建时不能在线(
ONLINE不支持全局分区索引),停机窗口必须预留充足
所以,真要跨分区高效查,优先考虑本地索引 + 分区裁剪;只有当查询条件几乎总是落在索引分区键上(比如总按 customer_id BETWEEN ? AND ? 查),才值得承担全局索引的维护代价。
最常被忽略的一点:全局分区索引的统计信息必须定期收集,且要用 DBMS_STATS.GATHER_INDEX_STATS 单独跑,GATHER_TABLE_STATS 不会自动覆盖它 —— 缺失统计会导致 CBO 误判执行计划,反而变慢。
本文共计1085个文字,预计阅读时间需要5分钟。
相关专题
GLOBAL PARTITION BY RANGE 不能直接创建在普通表上
oracle 中 global partition by range 只能用于本地索引(local)的“全局化”替代方案,但它本身不是一种独立的索引类型。你不能写 create index ... global partition by range 去直接建一个“全局范围分区索引”——语法会报错:ora-00922: missing or invalid option。
真正能用上的,是「全局分区索引」(Global Partitioned Index),它必须基于已分区的表(即表本身是 RANGE / LIST / HASH 分区),且索引的分区键可以不同于表的分区键。
- 表必须先按某种策略分区(例如按
order_dateRANGE 分区) - 全局索引需显式声明
GLOBAL PARTITION BY RANGE,并指定自己的分区列(如customer_id) - 全局索引的分区数、边界必须手动定义,不继承表的分区结构
建全局分区索引前必须确认表已分区
如果表没分区,CREATE INDEX ... GLOBAL 会失败,报错:ORA-14038: GLOBAL partitioned index must be created on a partitioned table。这不是权限或语法问题,是 Oracle 强制约束。
检查方式很简单:
SELECT partitioning_type, status FROM user_part_tables WHERE table_name = 'YOUR_TABLE';
- 返回空行 → 表未分区,得先
ALTER TABLE ... SPLIT PARTITION或重建为分区表 -
PARTITIONING_TYPE是RANGE/LIST/HASH→ 可继续 - 注意:即使表有子分区(composite),也算“已分区”,满足前提
GLOBAL PARTITION BY RANGE 的分区键必须可排序且稳定
你指定的索引分区列(比如 customer_id)会被用来划分全局索引的每个分区,它的值分布直接影响查询是否能走分区裁剪。如果选了一个高倾斜字段(如状态码 status IN (0,1)),会导致大部分数据挤在 1–2 个分区里,失去跨分区高效查询的意义。
- 推荐用主键前缀、时间戳、或业务上均匀分布的数字型字段
- 避免用
VARCHAR2长文本或含大量 NULL 的列 —— 分区边界定义困难,且MAXVALUE边界对 NULL 处理不直观 - 每个分区上限要预估:Oracle 要求所有分区键值必须落在显式定义的范围内,越界 DML 会报
ORA-14400: inserted partition key is outside specified partition
示例合法语句:
CREATE INDEX idx_global_cust ON orders(customer_id) GLOBAL PARTITION BY RANGE(customer_id) ( PARTITION p1 VALUES LESS THAN (10000), PARTITION p2 VALUES LESS THAN (20000), PARTITION pmax VALUES LESS THAN (MAXVALUE) );
全局分区索引维护成本高,DML 易阻塞
和本地索引不同,全局分区索引的任意分区都可能被单条 DML 影响(比如更新 customer_id)。这意味着:表的任何分区发生 UPDATE 或 DELETE,只要涉及索引键变更,就可能触发跨分区锁,甚至导致整个索引不可用。
- 表做
DROP PARTITION或TRUNCATE PARTITION时,全局索引会 INVALID,必须加UPDATE GLOBAL INDEXES子句,否则操作失败 - 批量插入若集中在某几个
customer_id段,会争抢同一索引分区的 latch,出现enq: TX - index contention - 重建时不能在线(
ONLINE不支持全局分区索引),停机窗口必须预留充足
所以,真要跨分区高效查,优先考虑本地索引 + 分区裁剪;只有当查询条件几乎总是落在索引分区键上(比如总按 customer_id BETWEEN ? AND ? 查),才值得承担全局索引的维护代价。
最常被忽略的一点:全局分区索引的统计信息必须定期收集,且要用 DBMS_STATS.GATHER_INDEX_STATS 单独跑,GATHER_TABLE_STATS 不会自动覆盖它 —— 缺失统计会导致 CBO 误判执行计划,反而变慢。

