---
title: "半结构化存储性能最佳实践 - OceanBase 最佳实践 | OceanBase 文档中心"
description: 半结构化存储性能最佳实践 本文档介绍了 OceanBase 数据库中半结构化存储的最佳实践，重点阐述如何通过半结构化编码存储技术降低 JSON 数据的存储成本。通过合理的配置和使用方法，用户可以在保证数据完整性的同时，显著减少存储空间占用。 背景 目前 JSON 等半结构化的数据，存在下面两个主要问题： 存储效率低下…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

# 半结构化存储性能最佳实践

更新时间：2026-07-28

[编辑](https://github.com/oceanbase/best-practices-doc/edit/master/zh-CN/1000.Performance-Tuning/700.semi-structured-encoding-best-practice.md) 适用产品： OceanBase 数据库 适用场景： 性能调优  

本文档介绍了 OceanBase 数据库中半结构化存储的最佳实践，重点阐述如何通过半结构化编码存储技术降低 JSON 数据的存储成本。通过合理的配置和使用方法，用户可以在保证数据完整性的同时，显著减少存储空间占用。

## 背景

目前 JSON 等半结构化的数据，存在下面两个主要问题：

- 存储效率低下：
     - 以二进制串形式存储，无法利用整数压缩等编码算法降低存储成本。
     - 冗余大量元数据信息，如每条 JSON 数据中重复存储 Key 字符串。
 - 查询性能受限：
     - 查询特定字段时必须读取完整数据，无法实现部分读取。
     - 查询性能受限于数据的完整读取开销。

为解决这些问题，OceanBase 引入了半结构化编码存储技术。该技术通过将 JSON 数据结构化存储，不仅显著提升存储效率，还提供了高效的字段查询能力。

### 基本原理

OceanBase 的半结构化编码存储技术通过将 JSON 数据拆分为多个子列进行存储，每个子列单独编码，从而提高编码压缩率，降低整体存储空间需求。

示例说明如下：

- 原始JSON数据：

  ```json
  {"id": 11111001, "name": "white", "score": 85.2}
  {"id": 11111002, "name": "brown", "score": 93.5}
  {"id": 11111003, "name": "mike", "score": 67.8}
  {"id": 11111004, "name": "trump", "score": 72.0}

  ```
 - 拆分后存储形式：

  ```
  | id       | name  | score |
  | -------- | ----- | ----- |
  | 11111001 | white | 85.2  |
  | 11111002 | brown | 93.5  |
  | 11111003 | mike  | 67.8  |
  | 11111004 | trump | 72.0  |

  ```

通过这种方式，系统可以对每列数据应用特定类型的高效编码方案，显著提高压缩率。

### 使用方式

半结构化编码存储使用方式，及条件查询性能优化说明请参见[使用半结构化编码](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002018088)。

#### 注意

如果启用半结构化编码功能，请务必保证集群配置项 [micro_block_merge_verify_level](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381833) 为默认配置 `2` ，切勿关闭微块合并校验。

## 适用场景

### 推荐场景

- 存储空间敏感型应用：适用于存储空间受限或存储成本敏感的场景。
 - 频繁基于 JSON 字段进行条件过滤的场景：如配置管理系统、产品目录系统、用户画像系统和事件追踪系统等。通过半结构化编码，可以显著提升查询性能。
 - 数据写入后较少完整读取 JSON 内容的场景：适用于主要进行数据写入和部分字段查询的场景，如日志采集系统、监控数据存储和事件追踪系统等。通过半结构化编码，可以优化部分字段查询。例如：

  ```json
  {"c1": "v1", "c2": "v2"}
  {"c1": "v1", "c3": ["v121", "v22"]}
  {"c1": "v3", "c2": "v5"}
  {"c1": "v4", "c4": ["v121", "v22"]}

  ```

  在处理此类数据时，由于字段 `c1` 出现频率很高，系统可将其识别为高频字段，并自动提取为单独列（column），采用高效的编码方式进行存储。这种方式有助于显著降低磁盘占用，并提升查询性能。
 - OBKV-HBase 时序场景：针对时序场景，OceanBase 基于 JSON 半结构化存储提供了优化的 OBKV-HBase 时序数据模式，有效解决原生模型中 K、T 字段重复存储的问题，优化写入性能和磁盘占用，详见下文。

### 不推荐场景

- 频繁完整读取 JSON 数据的场景：由于被拆分为多个子列存储，当读取 JSON 时，又需要把这些子列合并为原始的 JSON 输出，相比于不编码的 JSON，读取性能还是会不小的影响。所以如果会频繁读取 JSON 数据，则不建议开启。
 - JSON 数据完全异构的场景：因为 JSON 数据通常具有异构性，缺乏统一的结构，这种非结构化的数据在编码后难以实现有效的压缩，因此不建议开启。

### 触发限制

由于存在一些不适合的场景，半结构化编码并非在所有场景都会触发，以下情况不会触发：

- 拆分后存储空间大于拆分前：如果没有压缩收益，则没必要编码。
 - 无法提取公共 Schema：JSON 数据大多数异构性，会导致编码效果差，所以不触发。
 - 存在行外（outrow）存储的数据：如果使用本特性，需保证 95% 左右的数据都为行内存储。

无法提取公共 schema 的示例如下：

```json
# 字段完全不同
{"c1": "v1", "c2": "v2"}
{"x1": "v1", "x2": "v2"}

```

## 性能对比

### TPC-H 测试数据

我们对半结构化编码存储的性能进行了全面测试，包括存储空间和条件查询性能两个维度。测试使用了标准的 TPC-H 数据集，并与多种主流数据库系统进行了对比，以验证半结构化编码的实际效果。

| 存储类型 | 存储空间 | 条件查询(s) |
| --- | --- | --- |
| 关系表 | 387.086MB | 0.094 |
| 半结构化 JSON | 438.405MB | 0.223 |
| JSON Binary | 764.124MB | 24.445 |
| MongoDB | 1.32GB | - |
| Lindorm | 639MB | - |
| HBase | 1.23GB | - |
| MySQL | 2.10GB | - |

关键发现如下：

- 半结构化存储比原始 JSON 存储减少 42% 空间。
 - 条件过滤查询性能提升显著（百倍级别）。
 - 导入和合并性能略有下降（约 12-15%）。

## OBKV-HBase 时序模型

#### 注意

此功能从 V4.3.5 BP2 开始支持。

### 模型优化

针对时序场景，OceanBase 基于 JSON 半结构化存储提供了优化的 OBKV-HBase 时序数据模式，有效解决原生模型中 K、T 字段重复存储的问题。

数据转换示例如下：

原始数据：

```json
#
{"K": "name1", "T": 1732206353081, "cf1:QualifierA": "v1"}
{"K": "name1", "T": 1732206353081, "cf1:QualifierB": "v2"}
{"K": "name2", "T": 1732206353082, "cf1:QualifierC": "v3"}
{"K": "name2", "T": 1732206353082, "cf1:QualifierD": "v4"}

```

优化后 OBKV-HBase 存储格式：

```
| K       | Q          | T             | V    |
| ------- | ---------- | ------------- | ---- |
| name1   | QualifierA | 1732206353081 | v1   |
| name1   | QualifierB | 1732206353081 | v2   |
| name2   | QualifierC | 1732206353082 | v3   |
| name2   | QualifierD | 1732206353082 | v4   |

```

在时序场景下，原始数据中 K（行键）和 T（时间戳）字段会大量重复，特别是在一次 put 操作写入多个单元格时，K 和 T 字段完全相同，导致严重的磁盘空间浪费。同时，如果每个 V 值中包含大量重复的 Qualifier（列限定符），也会进一步增加存储开销。

通过半结构化编码，我们可以：

- 提取公共的 Schema。
 - 优化 Qualifier 的存储。
 - 减少重复数据的存储。

基于这些优化，我们调整了 OBKV-HBase 的存储格式。以示例数据为例，重新生成后的数据结构如下：

```
-- S 为该 cell 插入的当前服务端时间
| K       | T             | S             | V                                  |
| ------- | ------------- | ------------- | ---------------------------------- |
| name1   | 1732206353081 | 1732206353081 | {"QualifierA":v1, "QualifierB":v2} |
| name2   | 1732206353082 | 1732206353082 | {"QualifierC":v3, "QualifierD":v4} |

```

### 性能对比

我们对 OBKV-HBase 时序模型存储效率进行了测试：

| 存储类型 | 磁盘占用 |
| --- | --- |
| 半结构化时序模型 | 466.24MB |
| 普通时序模型 | 654.78MB |

## 未来规划

半结构化编码存储技术具有广泛的适用性和扩展性，未来 OceanBase 可能会扩展到 GIS/Array/Vector 等其他多模类型使用。这些扩展将基于现有的半结构化编码技术，进一步提升 OceanBase 多模数据处理方面的能力，为用户提供更全面的数据存储和查询解决方案。

## 附录

### 存储空间查询方法

这里介绍了通用的存储空间查询方法。

#### 系统租户查询

```sql
-- 获取 tablet_id
SELECT tablet_id FROM oceanbase.CDB_OB_TABLE_LOCATIONS
WHERE tenant_id=xxxx AND table_name='xxxxx';

-- 查询存储空间
SELECT size/1024.0/1024.0 FROM oceanbase.GV$OB_SSTABLES
WHERE tenant_id=xxxx AND tablet_id=xxxxx;

```

#### 普通租户查询

```sql
-- 获取 tablet_id
SELECT tablet_id FROM oceanbase.DBA_OB_TABLE_LOCATIONS
WHERE table_name='xxxxx';

-- 查询存储空间
SELECT size/1024.0/1024.0 FROM oceanbase.GV$OB_SSTABLES
WHERE tablet_id=xxxxx;

```

### 术语解释

- 半结构化编码：将 JSON 数据拆分为子列单独编码的存储技术。
 - 白盒过滤：直接基于编码数据进行的条件过滤操作。
 - outrow 存储：大字段数据单独存储的机制。
 - inrow 存储：数据与主记录一起存储的机制。

## 相关文档

- [OBKV-HBase 时序数据模式](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002022352#4-title-时序表)
 - [大对象存储性能最佳实践](https://www.oceanbase.com/docs/common-best-practices-1000000002081521)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
