源码解读:semi join 如何避免拉取大表数据?(一)

简介

背景

Hash join是解决复杂join的一个重要手段,但其无法避免拉取左右两端的数据到计算层进行计算,导致某些场景下执行效率不高。作为一种补充,bka join则可以利用OLTP数据库中的索引,通过join构造inner表的predicate命中表索引,在某些场景下有比较好的join效率。PolarDB-X是面向HTAP设计的分布式数据库,在复杂查询时也会重点考虑利用数据库的索引信息来提升join的查询效率,因此有了本文的semi bka join。

要解决的问题

在这篇源码解读中,我们要解决的是类似这样一条SQL的执行效率问题,select * from t1 where c1 in (select c1 from t2);其中t2为一张大表,t2表的c2列上有索引,t1为一张小表,且匹配后数据量很小。

Q:这个问题重要么?

A:其实还挺重要的,这代表了一类经典的TP型SQL,客户用的也比较多。

经典执行模式的不足

比如hash join,sort merge join,nested loop join,都需要把两张表的数据都拉取到计算节点,而t2是一张大表,导致执行效率不高。

解决方案

避免拉取t2这张大表的数据,引入semi bka join的执行模式,后面会详细展开。

讲述方式

为了避免大家在阅读源码时迷失在大量的细节之中,我们会用一种重构的形式来逐步构建semi bka join。同时,有些内容对于理解该部分设计,可能并没有太大的作用,比如代码中对于新分区表与老分区表的if eles判断,因此在重构中删除了该部分;最后,我们对于一些逻辑进行了重构,以便能够更加清晰的进行讲述。 综上,感兴趣的朋友可以参考我在https://github.com/wcf2333/galaxysql.git的代码提交记录,结合本篇文章阅读,体验会更好。

在分支refactor_semi_join分支上,移除了对于全局二级索引和新分区表的支持,精简了执行器的一些处理;

在wcf2333_build_semi_bka_join分支上,基于refactor_semi_join分支,首先移除了semi bka join的实现,然后逐步进行了丰富和实现,步骤可见提交记录,如下。

remove semi bka join and materialized semi join

add the simplest optimizer rule for semi bka join

add the simplest executor for semi bka join

support multi column in lookup predicate

enhance optimizer

support stream lookup join

support dynamic pruning

support single sharding key when table rule is not simple

support lookup predicate with multi-column when pruning

注:本文中bka(batch key access)和lookup表达相同的含义

目标

在写这篇文章时,是期望大家可以在学到一些东西之后,能够在一个暂时没有实现该功能的系统上真正实现一个semi bka join。它足够鲁棒,包含大量的细节,理想情况下足以在生产环境中使用。这也是为什么会花挺大力气采用重构的方式来写这篇文章的原因。 显然,一篇文章显然是不足以实现上述目标的,所以不出意外的话陆陆续续还会有几篇,我们期望回答所有重要的细节。因此,如果大家有什么问题的话,欢迎提问,无论是留言还是直接联系我,我们会在后续的文章中把大家的问题都囊括其中。 提醒:我们会在本篇中介绍一些细节,有些细节不进行debug可能不太容易理解,所以感兴趣的朋友可以搭建debug环境边阅读边调试。

前置知识

在理解semi bka join的详细设计和实现时,不可避免的要对其相关组件进行介绍,从中我们挑了两个重要的来展开介绍一下,hash join的核心设计与如何接入异步执行框架。

HashJoin的核心设计

我们之所以要讲解hash join的核心设计,是因为bka join与hash join有很多非常像的地方。理解了hash join,有助于我们更好的理解bka join。同时,这样的对比学习,可能会让大家有更多的收获。

hash join执行流程

hash join的左边是Outer端(探测hash table的一端),右边是inner端(构建hash table的一端),执行流程如下所示。

流程中的几个核心问题

1.保存在hash table中的是什么?

public class Concurren
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值