ob中局部索引与全局索引有什么区别呢?特别是在索引分区的情况下,全局索引分区后,分片会跟表的分片分布在一起,不就是局部索引的形式了吗?
即便全局分区索引碰巧分区规则、分片分布和主表完全对齐,它依然 ≠ 局部索引。二者本质定义、元数据绑定、DML机制、唯一性约束、分区运维逻辑完全不同,不能只看“物理分片是不是放在一起”。
一、OceanBase 局部索引(LOCAL) vs 全局索引(GLOBAL)完整区别
OB分区表二级索引分为两类:
1)局部索引 Local(局部分区索引)
2)全局索引 Global:再细分「全局非分区索引」、全局分区索引
1. 分区规则绑定关系(最根本区别)
局部索引 LOCAL
- 不需要单独定义分区;强制继承主表分区策略、分区键、分区数量。
- 主表 p0 → 索引p0;主表p1 → 索引p1,永久一对一绑定。
- 索引分区内的数据只会指向同一个主表分区的数据,不存在跨分区引用。
全局索引 GLOBAL(含全局分区索引)
- 拥有完全独立的分区定义,可以自定义分区方式、分区数量、分区键;
- 语法上必须显式声明
GLOBAL partition by xxx; - 允许和主表分区规则一致,也允许完全不同。
重点误区:“分区规则碰巧相同”只是一种可选场景,不是它的固有属性。
2. 物理存储与分区绑定(解答你的核心困惑)
-
局部索引
分区和对应主表分区逻辑绑定、调度绑定;分区迁移、副本切换、分裂合并,表分区与对应的索引分区作为一组整体移动。天然倾向同节点部署。 -
全局分区索引
哪怕分区规则和主表一模一样,二者分区是两套独立分区对象。
RootService负载均衡时,不保证索引分区和主表分区一定部署在同一台OBServer!
只是你观测时刚好放在一起,RS随时可能把索引分区调度到其他节点。
不存在强制绑定关系。
3. DML(增删改)执行代价、事务模型
局部索引
一条数据只落在单个主表分区,只需要修改对应的那一个局部索引分区;
所有修改都在同一个分区内完成,本地事务,无分布式事务开销。
全局分区索引
行数据在主表的分区、索引键落在全局索引的分区,二者是两套独立分区计算逻辑。
极端场景:同一行,主表在p0,索引记录落在全局索引p5。
更新时,需要同时修改两个独立分区,可能触发分布式事务、跨节点RPC。
哪怕现在分片在同一台机器,逻辑上依然是两个独立分区对象,执行路径不会简化成本。
4. 唯一索引约束(高频考点 OBCA/OBCP)
-
LOCAL 唯一索引
只能保证分区内唯一;无法全局唯一。
语法强制要求:局部唯一索引必须包含主表分区键。
-- 主表 partition by hash(a)
create unique index uk on t(b) local; -- 直接报错!
create unique index uk on t(b,a) local; -- 合法
-
GLOBAL 唯一索引
天然保证整张表全局唯一;不需要包含主表分区键。
这也是业务最常用全局索引的场景:需要对非分区字段建立全局唯一性。
5. 分区DDL(分裂、合并、新增分区)行为
- 局部索引:跟随主表自动执行分区分裂/合并,不需要单独维护索引。
- 全局分区索引:主表分区操作完全不会影响全局索引分区;你需要单独管理索引分区生命周期。
6. 查询逻辑差异
局部索引扫描:先定位主表分区 → 只扫描该分区对应的局部索引;索引里所有rowkey一定归属当前分区。
全局分区索引扫描:先按索引自身分区规则裁剪,查到主键后,通过主键路由去定位主表分区,查到的主键可以指向主表任意分区。
二、专门解答你的灵魂疑问
“全局索引分区后,分片会跟表的分片分布在一起,不就是局部索引的形式了吗?”
三点关键反驳:
-
“物理刚好在一起 ≠ 逻辑绑定”
局部索引是机制强制一对一绑定;全局分区索引只是调度巧合同节点,没有任何机制保证永久共存,RS负载均衡随时打散。 -
分区对象是两套独立元数据
LOCAL索引分区是依附主表分区的附属结构;
GLOBAL分区索引在系统视图__all_partition里是独立的分区条目,占用独立分区配额。 -
执行引擎代码路径完全不同
优化器、DML事务、唯一性校验、分区DDL走两套代码;
不会因为分片位置重合,就自动退化成局部索引的低成本执行逻辑。
举个直观例子:
主表 hash(a) 4分区
方案A:create index idx on t(b) local;
方案B:create index idx on t(b) global partition by hash(a) partitions 4;
表面分区策略一模一样,但:
- B支持建
unique index idx(b) global(不需要带上a);A做不到; - B的数据更新有可能产生分布式事务,A永远本地事务;
- OB官方文档明确建议:分区规则一致时优先选LOCAL,不要使用GLOBAL,全局索引维护成本更高。
三、最简对比汇总表
| 对比维度 | 局部索引 LOCAL | 全局分区索引 GLOBAL PARTITION |
|---|---|---|
| 分区规则 | 强制继承主表,一一绑定 | 独立自定义,可和主表相同/不同 |
| 分区对象 | 附属主表分区 | 独立分区,单独占用分区配额 |
| 唯一约束 | 仅分区内唯一;必须包含表分区键 | 全局唯一,无强制要求 |
| DML事务 | 单分区本地事务,无分布式开销 | 可能跨分区,存在分布式事务风险 |
| 分区迁移 | 与对应表分区整体调度 | 调度互不绑定,可能跨节点分离 |
| 分区DDL | 跟随主表自动维护 | 需要独立管理索引分区 |
| 适用场景 | 查询携带分区键,追求写入性能 | 查询不带分区键、需要全局唯一约束 |
学习~~