卢沙野大使接受法国LCI电视台直播专访

【少儿禁】马建《亮出你的舌苔或空空荡荡》

外交部迅速反应:严正抗议美冻结全国人大14位副委员长资产,中方将反制

达赖叛逃时把人皮、头骨法器都送给了谁(胆小慎入)

列宁会如何看待宝马MINI“冰淇淋事件”

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

【StoneDB Class】入门第五课:StoneDB 中的表连接

全面拥抱开源的 StoneDB 2022-11-01

本次课程为大家讲述 StoneDB 中的表连接。StoneDB 的表连接方式有 Nested Loop Join、Sort Merge Join、Map Join、Hash Join,不同的连接方式有不同的使用场景,在 StoneDB 中使用最广泛的是 Map Join 和 Hash Join。下面为大家详细介绍上述提到的四种表连接方式。

Nested Loop Join

通过一个示例来理解 Nested Loop Join 的原理:

mysql> select count(*) from t1,t2 where t1.id <> t2.id and t1.last_name='八';+----------+| count(*) |+----------+|  9999998 |+----------+1 row in set (28.90 sec)

向右滑动代码

假设优化器会选择表 t1 为驱动表,表 t2 为被驱动表,Nested Loop Join 的执行过程如下:

1)遍历驱动表的结果集,取出结果集中的第1条记录;

2)遍历被驱动表的结果集,按照关联字段去判断被驱动表的结果集中是否存在匹配的记录,如果匹配成功,则返回数据,否则就被丢弃;

3)直到遍历完驱动表的结果集为止。

从执行过程可知,驱动表有多少结果集,被驱动表就需要扫描多少次。如果驱动表的结果集很大,被驱动表就要扫描很多次,SQL 的性能就会非常的差。在其它数据库中,如果表连接方式是 Nested Loop Join,且被驱动表的关联字段是索引字段,那么 Nested Loop Join 还是很高效的。但在 StoneDB 中,即使表连接的关联条件是等值查询,且被驱动表的关联字段是索引字段,优化器也不会选择 Nested Loop Join,而选择 Hash Join 或者 Map Join。

Nested Loop Join 的使用场景:多表关联的连接字段是非等值查询。

要想知道表与表之间进行关联使用的是哪种表连接方式,需要设置参数 tianmu_control_trace,然后查看 trace.log,trace.log 的默认保存路径在 log 目录下。

set global tianmu_control_trace=1;--SQLset global tianmu_control_trace=0;
more /stonedb57/install/log/trace.log

Sort Merge Join

通过一个示例来理解 Sort Merge Join 的原理:

mysql> select count(*) from t3,t4 where t3.id > t4.id and t3.last_name='八';+---------------+| count(*)      |+---------------+| 1618433818772 |+---------------+1 row in set (4.93 sec)

向右滑动代码

在多表关联返回较大数据量时,Nested Loop Join 存在性能问题,因此出现了 Sort Merge Join,Sort Merge Join 的执行过程如下:

1)根据谓词条件访问其中的一张表,得到的结果集按照表中的连接字段排序,排好序的结果集记为结果集 R1;

2)根据谓词条件访问另外一张表,得到的结果集按照表中的连接字段排序,排好序的结果集记为结果集 R2;

3)遍历结果集 R1,即取出结果集R1中的第1条记录去和结果集 R2 中按照连接字段判断是否存在匹配的记录,直到遍历完结果集 R1 中所有的记录。

从执行过程可知,Sort Merge Join 需要对连接字段进行排序,我们知道在数据库中做排序是比较消耗资源的,如果无法使用内存排序,那么就需要使用磁盘排序,磁盘排序会生成临时文件,导致大量 IO 和空间占用等问题。在未出现 Hash Join 之前,Sort Merge Join 是处理大数据较为理想的表连接方式。

Sort Merge Join 的使用场景:多表关联的连接字段出现大于、小于比较。

Hash Join

通过一个示例来理解 Hash Join 的原理:

mysql> select count(*) from t2,t3 where t2.first_name=t3.first_name;+---------------+| count(*)      |+---------------+| 1303595576856 |+---------------+1 row in set (2.46 sec)

向右滑动代码

假设优化器会选择表 t2 为驱动表,表 t3 为被驱动表,Hash Join 的执行过程如下:

1)在内存中建立 hash table,根据 hash 函数计算出表 t2 结果集中关联字段的 hash value,将计算出的 hash value 存放到内存的 hash table;

2)根据 hash 函数计算出表 t3 结果集中关联字段的 hash value;

3)表 t3 结果集中关联字段的 hash value 与内存中的 hash table 进行匹配,如果匹配成功,则返回数据,否则就被丢弃。

从执行过程可知,每张表只需要扫描一次,hash 函数可以把 hash value 均匀地打散,匹配的效率还是非常高效的。

Hash Join 的使用场景:多表关联返回大量数据,且连接字段必须是等值查询。

Map Join

通过一个示例来理解 Map Join 的原理:

mysql> select count(*) from t2,t3 where t2.id = t3.id;+----------+| count(*) |+----------+|  5000000 |+----------+1 row in set (14.49 sec)
mysql> set global tianmu_force_hashjoin=on;Query OK, 0 rows affected (0.01 sec)
mysql> select count(*) from t2,t3 where t2.id = t3.id;+----------+| count(*) |+----------+| 5000000 |+----------+1 row in set (2.40 sec)

向右滑动代码

Map Join 的执行过程与 Hash Join 的执行过程很相似,通常情况下 Hash Join 算法比 Map Join 高效,如果把参数 tianmu_force_hashjoin 打开,原本优化器选择的表连接方式是 Map Join,现在会选择 Hash Join。 

以上是本次课程的全部内容,感谢各位继续关注。如果您对 StoneDB 感兴趣,欢迎前往 StoneDB 代码仓库了解更多,期待您的加入。

官网:https://stonedb.io/

Github: https://github.com/stoneatom/stonedb





END





可扫码添加小助手

加入StoneDB开源社区用户群

讨论交流,共同进步



【StoneDB Class】入门第四课:StoneDB 的体系结构
【StoneDB Class】入门第三课:StoneDB 的安装编译
【StoneDB Class】入门第二课:StoneDB 整体架构解析
【StoneDB Class】入门第一课:数据库知识科普
如何给一个 HTAP 数据库做基准测试?| StoneDB学术分享会 #4

文章有问题?点此查看未经处理的缓存