基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
OceanBase 列存(Column Store)知识点
更新时间:2026-08-17 06:36
总结说明
OceanBase 列存通过 Column Group 机制将基线数据按列独立存储,结合增量行存与基线列存的 LSM-Tree 架构,在保证 DML 写入性能的同时,大幅提升分析型查询(扫描、过滤、聚合)的效率。它支持纯列存、行列混存及列存索引等多种部署形态。
详细说明
概念定义
OceanBase 列存(Column Store)是一种将基线数据按列独立存储的存储格式。与传统的行存(Row Store)将一行所有列的数据聚集存储不同,列存将每一列的数据单独组织为一个 SSTable。查询时只需读取涉及的列,从而大幅减少 I/O 开销。由于同一列的数据类型一致,列存还能获得更高的压缩效率。
Column Group —— 列存的基本单元
Column Group(CG)是 OceanBase 列存的核心概念。
| 关键字 | 含义 | 效果 |
|---|---|---|
each column |
每列单独一个 CG | 纯列存,每列独立存储为一个 SSTable |
all columns |
所有列合成一个 CG | 行存 |
| 两者组合 | 同时存在行存 CG 和列存 CG | 行列混存,数据冗余两份 |
增量行存 + 基线列存
OceanBase 基于 LSM-Tree 架构,数据天然分层。
| 层级 | 数据类型 | 存储格式 | 说明 |
|---|---|---|---|
| 内存(MemTable) | 增量数据 | 行存 | 所有 DML 操作在此完成 |
| 磁盘(Minor SSTable) | 增量数据 | 行存 | 近期写入的数据 |
| 磁盘(Major SSTable) | 基线数据 | 列存 | 后台合并时由行存转换为列存 |
关键点:
- 增量数据始终以行存格式存储,确保 DML 操作性能不受影响。
- 基线数据以列存格式存储,提升分析查询效率。
- 读取时,系统会自动融合增量行存和基线列存的数据。
使用场景
三种存储模式选型
| 存储模式 | 建表方式 | 适用场景 | 优缺点 |
|---|---|---|---|
| 纯行存 | 默认建表 | 以 TP(事务处理)为主 | 写入性能最优,AP(分析处理)查询较慢 |
| 纯列存 | WITH COLUMN GROUP(each column) |
以 AP(分析处理)为主 | 压缩比高,分析查询快 |
| 行列混存 | WITH COLUMN GROUP(all columns, each column) |
HTAP(混合负载) | TP 和 AP 场景均可兼顾,但存储空间翻倍 |
使用方法
1. 创建列存表
-- 创建纯列存表
CREATE TABLE orders_col (
order_id BIGINT PRIMARY KEY,
user_id BIGINT,
amount DECIMAL(10,2),
status VARCHAR(20),
created_at DATETIME
) WITH COLUMN GROUP(each column);
-- 创建行列混存表(兼顾 TP 与 AP)
CREATE TABLE orders_hybrid (
order_id BIGINT PRIMARY KEY,
user_id BIGINT,
amount DECIMAL(10,2),
status VARCHAR(20),
created_at DATETIME
) WITH COLUMN GROUP(all columns, each column);
2. 创建列存索引
-- 在行存表上创建列存索引
CREATE INDEX idx_col ON orders(user_id, amount, created_at)
WITH COLUMN GROUP(each column);
3. 已有表行存转列存
-- 将行存表转换为列存表
ALTER TABLE orders ADD COLUMN GROUP(each column) [DELAYED];
-- 将行存表转换为行列混存表
ALTER TABLE orders ADD COLUMN GROUP(all columns, each column) [DELAYED];
说明
添加
DELAYED选项后,实际的行转列操作将在下一次合并(Compaction)时完成,期间不阻塞业务。
4. 设置默认存储格式
-- 租户级配置:后续新建的表默认采用列存格式
ALTER SYSTEM SET default_table_store_format = 'column';
说明
- 参数取值说明:
'row':默认行存(系统默认值)。'column':默认纯列存(自动添加each column)。'compound':默认行列混存(自动添加all columns, each column)。- 此配置仅对新建的主表生效,已有表不受影响。
5. Skip Index 列属性
列存数据按固定大小切分为数据块,每个块预存统计信息(如最小值、最大值、行数、SUM 等)。查询时可根据统计信息直接跳过不可能命中的数据块,无需解码。
-- 建表时指定 Skip Index
CREATE TABLE t1 (
c1 INT PRIMARY KEY,
c2 INT SKIP INDEX(MIN_MAX, SUM),
c3 VARCHAR(100) SKIP INDEX(MIN_MAX)
) WITH COLUMN GROUP(each column);
-- 对已有表的 c2 列新增 Skip Index 属性
ALTER TABLE t1 MODIFY COLUMN c2 SKIP INDEX(MIN_MAX);
说明
OceanBase 默认为列存表的每列自动创建 MIN_MAX 类型的 Skip Index。
6. Hint 手动指定引擎
-- 强制查询走列存引擎
SELECT /*+ USE_COLUMN_TABLE(orders) */ * FROM orders WHERE ...;
-- 强制查询走行存引擎
SELECT /*+ NO_USE_COLUMN_TABLE(orders) */ * FROM orders WHERE ...;
说明
对于行列混存表,优化器会自动选择最优引擎。仅在需要手动调优时才使用 Hint。
7. 确认查询是否使用列存
通过 EXPLAIN 命令查看执行计划。
EXPLAIN SELECT amount, status FROM orders_col WHERE user_id = 100;
关键标志:
| 算子名称 | 含义 |
|---|---|
COLUMN TABLE FULL SCAN |
使用了列存全表扫描 |
TABLE FULL SCAN |
使用了行存全表扫描 |
列存加速原理
只读所需列,减少 I/O
查询一张包含 100 列的表,执行 SELECT c1, c2 WHERE c3 > 10:
- 行存:需要读取全部 100 列的数据,浪费了 97 列的 I/O。
- 列存:仅需读取 c1、c2、c3 三列的数据,I/O 减少约 97%。
Skip Index 数据跳过
列存引擎利用数据块的统计信息(如 MIN/MAX)进行过滤,可以直接跳过不满足条件的数据块,无需解码数据。
例如,执行 WHERE age = 25:
- 数据块 1:min=30,max=50 → age=25 不可能在此块中 → 直接跳过。
- 数据块 2:min=18,max=28 → 可能包含 age=25 → 读取并检查。
- 数据块 3:min=40,max=60 → 直接跳过。
通过跳过大量不相关的数据块,查询效率得到大幅提升。
谓词/聚合下推
传统方式:存储层读取数据 → 传输给 SQL 层 → SQL 层进行计算。 列存引擎:将部分计算下推到存储层直接完成,仅将结果传输给 SQL 层。
支持下推的操作包括:
- 过滤下推:WHERE 条件在存储层直接过滤。
- 聚合下推:MAX、MIN、SUM、COUNT、NDV 等聚合函数在存储层直接计算。
- GROUP BY 下推:分组聚合操作在存储层完成。
适用版本
OceanBase 数据库 V4.4.3(oceanbase-4.3.3.0-100000412024101200)及以后版本