本集非常有意思,其中MongoDB 查询引擎的产品经理是吴晓晨,妥妥的中国人,身为一个中国人,为这样世界级的产品有一个中国的产品经理而高兴,说明中国人根本就不差,我们差的是舞台和XX。
正文:
大家好我是吴晓晨,我是MongoDB 的查询和性能部门的产品经理,这边的是我的同事Mihai这个产品的高级软件工程师,来Mihai给大家打一个招呼。大家好我是Mihai 我是MongoDB 查询引擎和性能部门的资深软件工程师。
吴晓晨:好的,今天我们将为大家介绍我们最新的,最好的查询引擎当然这不会是一个无聊的演讲,关于他是什么,他怎么工作,我们这里要回顾一些引擎底层的小故事,告诉你我们的思路是什么。今天的议程主要是以下几个部分,其中我们将详细介绍 SBE ,基于插拔数据库引擎的一个代表,Mihai将为我们介绍我们是如何进行构造以及细节,我们是怎么将这个引擎做的又快又好,量又足。后面我也将介绍我们的引擎未来的规划以及改进。
查询引擎就像汽车的发动机一样,在任何数据库中他都是明星和重点,一般查询引擎由三个部分组成。
查询分析器,查询优化器,查询执行引擎,查询引擎分析器主要的负责这些查询写法是否正确,查询的关键字是否正确,在验证这一切后,将语句发给查询优化器,优化器会产生多种的可以执行的计划,并从中挑选出最合适的,将计划发送给执行器,执行器将计划在集合中运行,并最终将结果获得后,返回给应用程序。
这里我们举一个例子,我们查询A=1 ,B=2 并且C 大于0 小于100并且展示A ,B ,KEY 同时对C 进行倒序排序,语句在发送给查询分析器后,会进行语句的整理,判断语句撰写的正确性,同时将整理好的语句发给查询优化器,产生执行计划,其中饱含了全表扫描进行数据过滤挑选展示字段和数据排序,最后在语句执行器中执行,并返回结果。
今天我们的重点不是query parser , query optimizer ,今天我们的重点是 查询执行引擎
下面我们Mihai将给我讲查询执行器方面的内容。
Mihai: 好的感谢晓晨,在我开始我的话题前我想先从传统的数据库引擎来开始我的话题,传统的引擎实际上一个将文档输入输出的过程,这对于我们引擎开发部门是一个非常传统和容易的实现的东西,实际上MongoDB存储的是JSON的数据,实现和处理都很简单 ,但现实是我们这样做是有成本的,因为在每个流程里面我们都时刻在关注着文档,这样做是不灵活的,实际上在上面的查询中我们只关注1-2个KEY 的值,但如果陷入了传统引擎的思路,则变成产生和消费文档的例行公事,成本消耗将是一个严重的问题,所以我们需要序列化和反序列化
这里我们看下面的查询以及执行计划,这里我们又四个文档,按照A=1 B=2 C >0 and C <100, 这里文档依次通过过滤器,则 2 和 4 号文档会留下,符合条件的,同时我们在将符合查询条件的数据放入到缓冲中,抛弃掉不用的KEY VALUE, 在将数据在缓冲中进行排序,这里你清楚的知道每个单独的查询组件都做了什么做了什么不同的事情,每个阶段关联不同的查询语义,无论我们做什么我们都产生文档,这就是我们执行的状态。
下面我们就介绍一下我们新的引擎,有谁知道SBE,请举手。嗯人不多,正如刚才晓晨讲的,SBE = slot based execution ,基于插槽方式的执行的方式,原来的经典引擎面对的是document 而现在的引擎基于的是值,我们要做的是把我们查询的值,调出来,然后和插槽进行绑定,插槽就有了唯一标识符,在整个的查询计划中使用这个值 ,所以我们从集合或任何其他的上下文中读取文档,新的方式中我们在并不是绑定文档,而是绑定文档里面的值或者是产生的中间的结果,这里最大的不同是
这里举了一个例子,由于例子比较晦涩难懂,这里用了其他的方式来说明他讲的这个问题,具体参加下图。
实际上,SBE引擎在MONGODB 5.1的版本就已经启用了,MongoDB的数据库系统中带有2个引擎,经典的引擎和SBE引擎,MongoDB 将自动的选择适合的引擎来执行查询。在MongoDB 6.0慢查询中可以通过queryFramework 来发现经典还是SBE得查询。使用SBE的查询类型有 group, lookup, match,project ,sort 等查询方式。
这里他讲授的例子,将查询的值作为一个变量带入到查询的结构体中,进行比较。
那么我们为什么开发了SBE数据库引擎,
1 原有的数据库引擎不够好,我们希望看到某种功能的改进,事实上构建SBE的初衷就是他能构建计划,仅仅对我们关心的文档进行处理
2 它将避免文档的具体化,我们不必每个阶段创建文档,从理论上讲,这会改善我们的查询延迟,在整个的查询过程中节省时间
3 SBE 还为我们的未来的优化给出了一条可优化的路径。
这里我们已经讲述了SBE的优点,那么我们团队是怎么做到这一点的,正如晓晨刚才提到的,这是一个花了多年的过程,在4.4发布的2019-2020年,当时实现了SBE的雏形,通过POC我们构建了等效的传统查询的SBE,明显查询的性能要优于之前的传统查询引擎,不幸的是我们由于发布的周期,我们仅仅在5.0上初步实现了一小部分,时间到了6.0这里我们化了一些时间,主要的目的是扩展SBE的功能集合。我们提供了$符号的查找,但是我们在一些更加细致的查询中,经典引擎的查询性能还是高于SBE,在7.0这个版本SBE走向了成熟,完全可以使用FIND来进行查询在2022年我们一年都在为提高SBE的性能做着努力。同时我们还要花费时间,将生成的计划做好,这是一件非常困难的事情。
同时我们还要证明,我们的SBE能给客户提供更好的性能,所以我们对于性能进行详细的工作和测试。这里他是漂亮的图标,同时他也是两个引擎比较重体现性能数据重要的部分。同时他也是我们工作成果的展示,以及体现我们最关心的性能回归和查询部分。
好的谢谢Mihai的介绍,大家都对新的7.0的新引擎激动吧,在你升级到MongoDB 7.0 新的引擎将直接变为SBE,无需你进行任何的操作。同时适合经典引擎的查询会直接使用传统的数据库引擎处理,第二件我今天将介绍一个DEMO
故事发生在一个零售的领域,Kyle 领导一只零售平台的团队,这个平台由两个部分组成,1 用户应用程序应用程序允许用户浏览过滤器排序,让客户来购买最终他们选中的商品,2 是内部的数字面板允许他们跟踪他们的供应商,也可以叫供应链。
这里有两个collections的设计,一个是供应商一个是产品,其中包含各种属性。
这里有两个查询 假设我要去朋友聚会我不知道该送什么,去他的生日会所以我决定买一些礼品卡,我登录了网站并且开始查看我可以买的礼品卡,我想找到价格低于50¥的并且具有20%折扣的。
使用过购物网站的都知道,你搜索出来的东西都是简单的介绍,无法看到有效的详细介绍,所以这里我们仅仅展示折扣和产品名称和价格并按照价格排序。第二个是一个聚合操作,在华盛顿州每个品类库存的总价,并提供全国可以提供产品的供应商名单,所以对于聚合,第一步是匹配按照州来进行筛选,然后我们进行分组并计算每个门类的总价格,查找最终汇聚出我们要的结果。后面是一个视频,通过Altas 来进行,这里他创建了两个集群 6.3 和5.0 来对同样的查询进行对比,这里简略其中的过程,直接说结果,结果是大约10.2毫秒,1000万的数据,经典的引擎是16毫秒,下面我们针对第二个查询将进行比对SEB需要13秒,经典需要21秒只做了查询的21%。
通过实际的查询我们让客户了解到SBE的性能,我们未来将把查询引擎做的更加稳定和高效。同时确保我们的每个查询都在最好的引擎上运行,在前面有一些同学介绍了数据平台的部分,这说明MONGODB 不是一个文档数据库,也不是一个仅仅可以插入,更新,删除数据的文档数据库,我们希望他是一个能够进行应用分析工作的产品。(MongoDB要进军 OLAP),所以我们希望我们的MongoDB 变得和混动汽车的发动机一样,具有双擎的力量。最重要的是我们要不断的改变,并让客户享受到最好的数据库引擎。