背景
OceanBase 4.3.0 版本推出了加速 AP 查询的列存引擎,具体包含:
- 新的列式编码
- 列预聚合信息
- 列存执行引擎
- 向量化内存格式
- 新的查询优化器,能根据规则和代价动态选择行存和列存引擎。
OceanBase 列存引擎发布之后,AP 分析能力得到了大幅提升,在与一系列竞品的对比测试中都有比较好的表现,正式踏入了 HTAP 领域。
为了节省存储成本和简化用户的运维,OceanBase 将 TP 和 AP 业务放在一套系统中,共享一份数据。实际的业务场景中,尤其是核心业务,往往有大量数据更新,这些业务也需要对数据做一些实时的数据分析,因此对 OceanBase 分析引擎提出了比较高的挑战。
在实战营(第三季)第一期的课程文档中,大家知道 OceanBase 采用的是 LSM Tree 的存储架构,数据分层存储,新数据追加写入最热层,并且只记录最新值。这种写入方式对 TP 系统比较友好(写多读少),但是因为查询采用的是 Merge-On-Read 的处理方式,所以当增量数据比较多时,对 AP 分析能力有一定的影响(读放大)。
为了消除增量数据对分析引擎的性能影响,OceanBase 在 4.3.5 版本中提出了 Merge-On-Write 表,将更新拆分成 delete / insert 写入增量数据中,查询时分别对增量和基线数据进行处理,从而显著地提高了更新频繁场景下 OceanBase 的实时分析能力。
边学边练,效果拔群
-
在线实验地址:《Delete-Insert 存储引擎》。
-
性能测试结果:merge-on-write 表,查询性能相对于 merge-on-read 表,会有 5 倍以上的提升。
-
这个实验有导入数据(大概要 100 秒左右)之类耗时较长的操作,大家可以一次性把实验文档所有 SQL 语句全都复制到右边的实验环境里去执行,然后一边等待最后的实验结果,一边阅读下面的文章内容。
-
在实验环境是在纯列存表上做了一个小规模数据的测试,在这个测试中,性能差异可能没有那么明显(不过 2 ~ 3 倍应该还是有的,为确保测试准确性,建议在实验环境中多次重复执行最后的性能对比 SQL,并取平均值 )。实际在更大规模数据或更高并发场景下(生产环境),才能真正体现出 merge-on-write 表的优势。
-
文档不可尽信,实践才出真知。
-
OceanBase 官网文档《创建表》中的创建 MOW 表的语法如下(截至 2025.10.22):
CREATE TABLE table_name column_definition MERGE_ENGINE = {delete_insert | partial_update} WITH COLUMN GROUP([all columns,] each column); -
语法中的 WITH COLUMN GROUP,看上去是建 MOW 表的必选项,所以貌似 只有列存表和行列混存表才能被设置 MOW 属性。
-
大家可以试一试,去掉 WITH COLUMN GROUP xxx,看看能不能把纯行存表也设置为 MOW 表?
-
大家还可以尝试看看能不能把实验环境中最初的两个建表语句改成纯行存表,然后再对比一下行存 MOW 表相比普通行存表的性能提升(多次执行查询,取平均值),看看能不能达到蒲华大佬宣称的性能提升 5 倍以上?
CREATE TABLE ct1 ( c1 INT, c2 INT, c3 DATE ) MERGE_ENGINE = DELETE_INSERT; CREATE TABLE ct1_normal ( c1 INT, c2 INT, c3 DATE );@兹拉坦 的猜想:
因为行存表的查询性能一般会比列存表更差,所以如果行存表可以设置 MOW 属性的话,性能提升幅度大概率也会比列存表更显著。(换句话说就是:进步快,源于起点低~
)大家可以在实验环境中通过测试,来验证下这个家伙的猜想是否正确?
如果不正确,可以再思考下为何不正确?
-
-
-
-
课后小测地址:【DBA 实战营】 Merge-On-Write 表
-
在第三季的活动中,每通过一个课后练习,就会自动获得 10 个社区积分,并获得一次抽奖的资格。抽奖时有机会获得实体礼物或更高额的积分奖励。
-
第三季课后小测,为了避免您等待人工审核,在最后一道问答题中,需要复制黏贴一个您在实验环境中通过
obclient -h127.0.0.1 -P2881 -uroot@mysql_tenant -A -Dtest链接到数据库后,执行select now(), GetKey('你的论坛用户名');后获取的字符串。 -
例如您的社区用户名叫作兹拉坦,需要复制黏贴到最后一道问答题中的字符串就是:
02095F4E60B29E8B709DB2773B18FDCB6E1365817C(不要截图,只需要复制黏贴字符串后上传到最后一道题的答题区域中即可)。obclient [test]> select GetKey('兹拉坦'); +--------------------------------------------+ | GetKey('兹拉坦') | +--------------------------------------------+ | 02095F4E60B29E8B709DB2773B18FDCB6E1365817C | +--------------------------------------------+ 1 row in set (0.001 sec)小提示:
- 需要先登录 OceanBase 账号,才能初始化屏幕右边的实验环境进行实验。
- 在实验环境里,干什么都可以。大家不要受限于屏幕左边的实验手册,可以天马行空地做一些你感兴趣的事情,或者验证一些你对 OceanBase 官网文档的疑问、以及自己的猜想等等 。
- 欢迎大家平时在学习 OceanBase 的过程中,也都能充分利用在线体验页面为您提供的一些实验环境,来体验 OceanBase 中您感兴趣的新特性。
-
希望大家都能够积极参与上面的在线体验,并通过课后小测。 这是 @兹拉坦 能够持续为大家更新《DBA 实战营(第三季)》课程内容的最大动力(真心十分感谢各位 OceanBase 社区用户的支持,让实战营能够一直活到现在)~
大家如果不来参加实验并通过小测,老大随时都可能会在社区里停止更新相关的课程,实战营就药丸啦!(按照目前通过课后小测的数据,每一期课程内容,都很可能是实战营的最后一期……)
大家快来参加实验,通过小测,救救孩子~














