Hash Join 中的 Bit Vector Filtering 优化

Bit Vector Filtering 是一种查询优化技术,在 Hash Join 落盘、分布式场景下能加快数据的查询。Bit Vector Filtering 的详细说明请参考 《Query Evaluation Techniques for Large Databases》 一文,12.4 Bit Vector Filtering 一节。本文简要介绍一下我对这个概念的理解。

Bit Vector Filtering, 在 Hash Join 的相关论文中通常称做 Bit Vector Filtering,不要以为是什么新技术,它还有一个你熟悉的名字:Bloom Filter。

具体做法如下:

  1. 构造一个长度为 N 个比特位的位图 b,所有比特位都初始化为 0;
  2. Hash Join 用左表的数据来 build hashtable 的同时,将 join key 的 hash 值模 N,得到值 m(0 <= m < N),然后将位图 b 的第 m 位设置为 1;
  3. Hash Join 用右表的行去 hashtable 中探测之前,先也用 join key 的 hash 值模 N,得到值 n(0 <= n < N),然后去位图 b 中检查第 n 位是否被置为 0,如果为 0,则直接丢弃右表的这一行。这样就可以避免一次查 hashtable。

一般来说,如果 N 是左表行数的 2 倍以上时,Bit Vector Filtering 的过滤效果会非常好。

Bit Vector Filtering 更有效的应用场景是 Hash Join 落盘。当左表无法全部放在内存时,需要落盘(详见 《Cost-Based Oracle Fundamentals》 的 Chapter 12 Hash Join 章节)。右表的行也需要落盘。在右表行数据落盘之前它可以先检查一下 Bit Vector Filter,如果不命中,可以直接丢弃,避免一次 IO 写。

除了落盘场景,还有分布式 Hash 的场景。左表建好 Bit Vector Filter 后可以将其发送到右表所在的多台机器。右表发送每一行数据到左表之前都会通过 Filter 过滤一下,如果不命中,则可以不发送这一行。通过这种方式可以有效地减少网络传输 IO ,以及减少 Hashtable 探测的次数。

开个脑洞,配合适当的技术, Bit Vector Filter 下压到存储层,行扫描的结果很多都不用写 buffer,直接丢弃即可。这样可以有效降低右表扫描的内存使用量。所谓配合适当技术,是指存储层对 join key 的 hash 计算结果不应该丢弃,而应该和行一起存起来(或者是用 hash 算出 partition id 后存 partition id),这样就可以避免数据从存储层吐出后还需要再重复计算一次 Hash 值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值