国产数据库 - 内核特性 - CloudberryDB中的Runtime Filter

2024-06-24 08:52

本文主要是介绍国产数据库 - 内核特性 - CloudberryDB中的Runtime Filter,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

国产数据库 - 内核特性 - CloudberryDB中的Runtime Filter

今年5月份GreenPlum官方将GitHub仓库代码全部删除,各个分支的issues和bugs讨论等信息全部清除,仅将master分支代码进行归档。对于国内应用GPDB的用户来说,这是一个挑战性事件,对与后期维护、升级等都变得非常困难。有幸HashData开源了基于GP衍生版本CloudberryDB版本,对国内GP用户来说是一个及时的福音。

今天介绍下CloudberryDB中的Runtime Filter。它实现了两种runtime filter方式。一种是:新增了RuntimeFilter算子,在Hash Join算子的探测端添加RuntimeFilter算子,当然这就导致仅在RuntimeFilter算子实现提前过滤,并未将filter下沉到SeqScan算子或者TableAM层,仍旧存在不必要的算子计算。另一种是将runtime filter下推到SeqScan或者TableAM,尽量能够提前终止算子执行。后一种方式目前仅处于开发阶段,并未release,期待该功能尽快完善。

1、RuntimeFilter算子方式过滤

045902f40ee015cc5105a3a9f1fde737.png

从上面执行几乎也可以看出,仅在Hash Join的探测端挂载了一个RuntimeFilter算子。首先看下该算子是怎么执行的。

1.1 结构体之间关系

c47a56757e2098e1560bdf137fb24728.png

主要关系是:HashJoin的运行时结构体HashJoinState的JoinState js即PlanState ps中有左右子节点的执行计划节点。左子树为探测端结构体RuntimeFilterState,执行运行时过滤的动作;右子树为HashState节点,rfstate为RuntimeFilterState地址。由此保证内表构建时,构建的bloom bitmap可以关联到探测端扫描外表时判断外表值是否在bloom bitmap中。

1.2 具体流程

24462ac9275a6c6f619fb86838bd8b44.png

1)MultiExecPrivateHash构建完hash表后,标记build_finish为true,确保RuntimeFilter节点执行时可以进入布隆过滤

2)MultiExecPrivateHash构建hash表时,调用ExecHashGetHashValue将内表值的join字段hash后放到bf中

3)ExecRuntimeFilter执行时,判断外表值是否在bf中,若在则将其输出,若不在则过滤掉,不进入join

4)可以看到,这种运行时过滤方式,仅将过滤下沉了一个执行节点,底层节点的扫描等多层执行计划节点并没有最优地避免执行,效果也不会太好。

2、filter下沉到SeqScan的方式

我们看下另一种实现方式,将布隆过滤下沉到SeqScan底层节点,这种方式比较彻底,可以尽最大可能减少不必要节点执行。

该patch可查看:

https://github.com/cloudberrydb/cloudberrydb/pull/405

Hash执行时构建布隆过滤器的流程如下图所示:

32118e1a2c3e04338275549132e831ac.png

1)通过gp_enable_runtime_filter_pushdown配置项开启该功能

2)BuildRuntimeFilter函数用于构建布隆过滤器,对于每个外表值都将其构建到af->bf中

3)当内表值都构建到hash表,并完成布隆过滤器的build后,通过PushdownRuntimeFilter函数将布隆过滤器通过scankey的形式下推到SeqScan节点的filters链表中。af->target即为SeqScan节点。

SeqScan节点执行时即可通过布隆过滤器进行过滤,流程如下图所示:

c5c19c6e04cdfc00befb52cee64b3e6c.png1)对于表的每行记录都通过PassByBloomFilter进行判断,看它在没在bloom bitmap中,若在就向上层节点推出记录,否则过滤掉,扫描下个记录。由此可见,在hash join中将join条件过滤提前到了SeqScan位置,大大减少了中间算子的计算。

2)还需要考虑一个问题:如何将HashJoin的Hash子节点的布隆过滤器和下沉对象SeqScan关联起来。

c109272170eef176fc3991b465111704.png

1)HashJoin算子初始化时ExecInitHashJoin通过CreateRuntimeFilter函数构建布隆过滤器和下沉位置的关系

2)通过FindTargetAttr函数遍历HashJoin的左子树,找到SeqScan节点,该节点即为下沉到的对象

3)HashState中的filters链表存储AttrFilter *af。af->bf和af->target构成了布隆过滤器和SeqScan节点的关系。

由此,可见这种方式实现原理上比较完善,可以尽可能的减少中间算子的计算。当然,对于CloudberryDB来说,该功能还未release,期待尽早release。

这篇关于国产数据库 - 内核特性 - CloudberryDB中的Runtime Filter的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089682

相关文章

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

C#实现文件读写到SQLite数据库

《C#实现文件读写到SQLite数据库》这篇文章主要为大家详细介绍了使用C#将文件读写到SQLite数据库的几种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录1. 使用 BLOB 存储文件2. 存储文件路径3. 分块存储文件《文件读写到SQLite数据库China编程的方法》博客中,介绍了文

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发

如何安装HWE内核? Ubuntu安装hwe内核解决硬件太新的问题

《如何安装HWE内核?Ubuntu安装hwe内核解决硬件太新的问题》今天的主角就是hwe内核(hardwareenablementkernel),一般安装的Ubuntu都是初始内核,不能很好地支... 对于追求系统稳定性,又想充分利用最新硬件特性的 Ubuntu 用户来说,HWEXBQgUbdlna(Har

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica