楔子
@兹拉坦 刚上小学时,很喜欢玩儿任天堂 Game Boy 游戏机上《口袋妖怪》系列的 RPG 游戏。
当时游戏卡带中需要用一个记忆纽扣电池给 SRAM 供电,但从奸商手里买到的 N 手游戏卡带,记忆电池往往都已经没电了,每次游戏的进度存档都会莫名其妙地消失。
当时互联网还不是很发达,兹拉坦每天只能一遍一遍地从家门口重新开始,走出新手村 “真新镇和常磐森林”,都已经是小半年之后的事情了。真是一段痛苦的回忆……
物化视图相比普通视图,就类似于卡带中有了这个用于存储 “视图定义 SQL 计算结果” 的记忆电池,让用户准备在基于视图进行下一步计算时,不需要每次都再重新计算之前视图已经算出的结果。
除此以外,OceanBase 还可以通过配置物化视图增量刷新,支持后台定期刷新出物化视图的最新结果。
背景
假设你是一名数据分析师,你的任务是从包含数百万行数据的数据库中,反复检索特定的信息,每次查询都需要执行耗时耗资源的计算,你就可以通过物化视图来提高查询效率。
类似下图中的统计信息大盘、监控页面、报表指标中心等等,页面里面的指标往往有秒级,分钟级,小时级等等聚合数据,需要提前通过物化视图聚合,才能高效展示。
接下来用 OceanBase 的一个用户 —— 淘宝收藏夹举个例子:
-
用户收藏的商品存储在收藏信息表里面 collect_info。
create table collect_info(user_id int, item_id int); -
如果需要计算单个商品的收藏数,用于收藏热度排序,就可以创建一个物化视图,每 5 分钟刷新一次,来统计商品 (item_id) 的实时收藏次数。
-- 伪 SQL,只用来进行示例 create materialized view item_collect_count refresh fast start with sysdate() next sysdate() + interval 5 second as select count(*) from collect_info group by item_id;
什么是物化视图?
物化视图是一种特殊的视图,它存储了视图定义中查询执行的结果,这个过程就是物化。通过保存某些耗时操作的结果,方便在查询时直接查询已经预计算好的数据 ,避免重复执行这些耗时耗资源的操作,通过空间换时间来加速查询。
物化视图和普通视图有什么区别?
- 普通视图只是存储了视图的定义,用户每次查询视图的时候,都会重新执行视图定义中的查询语句。
- 物化视图有一个容器表用于存储视图定义中查询语句执行的结果,用户查询视图时,只需要查询容器表即可。物化视图为了保存结果的时效性,还会定期执行视图查询语句刷新容器表中的结果,这样用户在查询时,无需每次都对视图的定义进行实时计算。这种预先计算的方式大大提升了查询性能。
边学边练,效果拔群
在本期实战营课程中,就由 OceanBase 优化器研发负责人山文大佬,通过一个在线体验实验《使用物化视图构建宽表加速多维分析》,为大家展示在 AP 场景下,如何使用物化视图构建宽表加速多维分析。
在实验中,大家可以直观地对比出 AP 场景下传统的多表 JOIN 查询,和基于物化视图查询的巨大性能差异。
随着数据量增长,性能差距将指数级扩大。在百万级订单场景下,物化视图可将查询从分钟级降至秒级,甚至毫秒级。
-
在线实验地址:《OceanBase 物化视图》
说明
这篇教程里提到了一些偏底层实现的内容,例如:
一张物化视图,在 OceanBase 的内部元数据管理中,实际被分为了两个表:
- 一个是物化视图本身的 schema,和普通的 view 类似。
- 另外一个是隐藏的普通表,这个普通表用于存储实际的物化视图数据,我们称之为物化视图的容器表。
希望进一步了解数据库中物化视图底层实现的同学,看到本文中类似的东西,都可以到在线体验环境中,通过查询 oceanbase.__all_table 之类的系统表,看看这两个东西到底长什么样子。
除此以外,也可以想办法去看下任何你感兴趣的东西,例如物化视图全量刷新时创建的那个隐藏表、增量刷新的物化视图日志表等等。
-
课后小测地址:【DBA 实战营】OceanBase 物化视图
-
在第三季的活动中,每通过一个课后练习,就会自动获得 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 中您感兴趣的新特性。
-
希望大家都能够积极参与上面的在线体验,并通过课后小测。这是 OceanBase 社区能够持续为大家更新《DBA 实战营(第三季)》课程内容的最大动力~

这期是第三季 OceanBase 实战营活动的最后一期。
今年五月中旬开始,OceanBase 开源团队的社区运营同学兹拉坦,发布了第一季的第一期内容,之后连续完成三季实战营课程的内容更新,感谢各位社区用户长久以来对社区课程和活动的支持!
兹拉坦深知水平十分有限,特别感谢各位社区用户对兹拉坦和实战营课程中种种不足的包容!跪谢大家一直惯着兹拉坦~


















