首批通过分布式安全可靠测评,为关键业务系统打造
列存 FAQ
更新时间:2026-04-30 19:06:39
列存允许增删列吗?
允许增加列和删列。
支持 Varchar 列字符数改大、改小。
列存支持多种 Offline DDL,和行存表无异。
有关列存修改的详细信息请参见表行存列存转换(MySQL 模式)和表行存列存转换(Oracle 模式)。
列存表的查询有何特点?
冗余行存表中,列存表查询逻辑默认采用 Range Scan 走列存模式,而 Point Get 查询则会回退到行存模式。
纯列存表中,任何查询都采用列存模式。
列存支持事务吗,对事务大小有什么限制?
和行存表一样,支持事务,并且事务大小无限制,具备高一致性。
列存表的日志同步、备份恢复等有什么特别之处吗?
没有任何特别之处,和行存表一致。同步的日志都是行存模式。
是否支持将行存表用 DDL 变成列存表?
支持。通过加列存、删行存实现。相关语法示例如下:
create table t1( pk1 int, c2 int, primary key (pk1));
alter table t1 add column group(all columns, each column);
alter table t1 drop column group(all columns, each column);
alter table t1 add column group(each column);
alter table t1 drop column group(each column);
说明
alter table t1 drop column group(all columns, each column); 执行后,不用担心没有任何 Group 来承载数据,所有列会被放到一个叫做 DEFAUTL COLUMN GROUP 的默认 Group 中。
列存里支持多个列集合在一起吗?
在 OceanBase 数据库 V4.3.0 版本中,仅支持要么每个列独立存储,要么所有列一起作为行存储。暂不支持任选若干列集合在一起存储。
列存支持更新吗,以及 MemTable 里的结构是怎样的?
在 OceanBase 数据库中,增删改操作都在内存里完成,数据以行存的形式保存在 MemTable 里;而基线数据是只读的,以列存的形式保存在磁盘上。当读取一列数据时,会实时地融合 MemTable 中的行存数据和磁盘里的列存数据,输出给用户。这意味着,OceanBase 数据库支持强一致读列存,不会有数据延迟。写入 MemTable 的数据支持转储,转储数据依然以行存的形式保存。合并后,行存数据和基线列存数据融合,形成新的基线列存数据。
注意
对于列存表来说,如果存在大量的更新操作,并且没有及时合并,查询性能会受到影响。因此,推荐在批量导入数据后发起一次合并操作,以获得最优的查询性能。而少量更新操作对性能影响不大。

支持对列存的某一列建索引吗?
支持。OceanBase 数据库不区分是对列存建索引,还是对行存建索引,创建的索引结构是一样的。
对列存某一列或几列建索引的意义在于可以构造一个覆盖索引,提升点查询性能,或者对特定列做排序以提升排序性能。
“列存索引”是什么?
OceanBase 数据库还支持列存索引的概念,不同于“对列存建索引”。列存索引指的是索引表的结构是列存格式。
例如,我们已经有行存表 t6 ,希望对 c3 求和且性能最好,这时可以对 c3 建一个列存索引:
create table t6(
c1 TINYINT,
c2 SMALLINT,
c3 MEDIUMINT
);
create /*+ parallel(2) */ index idx1 on t6(c3) with column group (each column);
除此之外,我们还支持更多索引创建方式:
支持索引中冗余行存。
create index idx1 on t1(c2) storing(c1) with column group(all columns, each column); alter table t1 add index idx1 (c2) storing(c1) with column group(all columns, each column);支持索引中纯列存。
create index idx1 on t1(c2) storing(c1) with column group(each column); alter table t1 add index idx1 (c2) storing(c1) with column group(each column);
在数据库索引中使用 STORING 子句的目的是存储额外的非索引列数据到索引中。这可以为特定的查询提供性能优化,既可以避免回表,也可以降低索引排序的代价。当查询仅需要访问存储在索引中的列,而不需要回表查询原始行时,可以大幅提升查询效率。
列存表与列存副本的区别是什么?
列存表是指表的分区 Leader & Follower 的 Schema 均为列存格式,并且 OLAP 的查询可以是强读;而列存副本是在保证表的分区 Leader & Follower 的 Schema 为行存格式的前提下,只读副本 Learner 为列存格式,并且 OLAP 的查询只能是弱读。
什么是列存副本自动选择?
OceanBase 数据库 V4.6.0 版本引入了列存副本自动选择功能。简单来说,这个功能能够:
- 自动识别:系统会自动识别哪些查询适合使用列存副本(AP 查询)。
- 智能路由:根据查询特征和代价,自动将合适的查询路由到列存副本执行。
- 统一入口:TP 和 AP 流量使用同一个入口,无需手动切换。
为什么需要列存副本自动选择功能?
在 HTAP(混合事务分析处理)场景中,业务通常包含两类不同的查询:
| 查询类型 | 特征 | 适合的存储 |
|---|---|---|
| TP 类查询(事务处理) | 短查询、高 QPS、对延迟敏感、访问数据量小 | 行存副本(利用索引加速) |
| AP 类查询(分析处理) | 大查询、低 QPS、延迟不敏感、访问数据量大 | 列存副本(利用列存和并行化加速) |
在 OceanBase 数据库 V4.6.0 版本之前的版本中,如果要将查询路由到列存副本,需要手动设置 ob_route_policy = 'COLUMN_STORE_ONLY',这种方式存在以下问题:
- 使用门槛高:需要用户自己判断哪些查询是 AP 查询,然后手动配置。
- 无法自适应:无法根据查询特征自动判断,配置后所有查询都会走列存副本。
- 强读限制:不支持强一致性读,只能使用弱读,限制了使用场景。
如何判断查询是否路由到了列存副本?
查看执行计划:如果一张表在 F 副本没有列存,扫描算子却是
COLUMN TABLE FULL SCAN,说明查询被路由到了列存副本。查看 Outline:更准确的方式是查看
outline data,如果出现OPT_PARAM('AP_QUERY_ROUTE_POLICY' 'FORCE')的 Hint,说明确实路由到了列存副本。例如:/*+ ... OPT_PARAM('AP_QUERY_ROUTE_POLICY' 'FORCE') ... */