Clickhouse中支持的Join类型

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: 此为Join探索系列的第一篇

ClickHouse是一个开源的面向列的数据库管理系统(DBMS),专为需要在大量数据上进行超低延迟分析查询的用例进行构建和优化。为了实现分析应用的最佳性能,通常会将表合并为一个称为数据去规范化的过程。扁平化的表通过避免连接操作来最小化查询延迟,但会增加增量ETL的复杂性,通常可以接受以换取亚秒级的查询性能。
然而,对于某些工作负载,例如来自传统数据仓库的工作负载,去规范化数据并不总是可行的,有时分析查询的源数据的一部分需要保持规范化。这些规范化的表占用更少的存储空间,并提供了数据组合的灵活性,但对于某些类型的分析需要在查询时进行连接操作。
幸运的是,与一些误解相反,ClickHouse完全支持连接操作!除了支持所有标准的SQL JOIN类型外,ClickHouse还提供了其他适用于分析工作负载和时间序列分析的JOIN类型。ClickHouse允许您在连接执行时选择6种不同的算法(我们将在博客系列的下一部分中详细探讨),或者允许查询规划器根据资源可用性和使用情况在运行时自适应选择和动态更改算法。
在ClickHouse中,即使是对大型表的连接操作也可以实现良好的性能,但这种用例尤其需要用户仔细选择和调整连接算法以适应其查询工作负载。虽然我们预计随着时间的推移,这种过程也会变得更加自动化和启发式驱动,但本博客系列提供了对ClickHouse连接执行内部原理的深入了解,以便您可以为应用程序常用的查询优化连接操作。
在本文中,我们将使用一个规范化的关系数据库示例模式,以演示ClickHouse中可用的不同连接类型。在接下来的文章中,我们将深入了解ClickHouse中可用的6种不同的连接算法。我们将探索ClickHouse如何将这些连接算法集成到其查询流水线中,以尽快执行连接类型。未来的部分将涵盖分布式连接操作。

Test Data and Resources
我们使用Venn图和示例查询来解释ClickHouse中可用的连接类型,这些示例查询基于来自关系数据集存储库的规范化IMDB数据集。
创建和加载表的说明:
Join1.png
上面的4个表中的数据代表movies。一个电影可以有一个或多个genres。电影中的roles由actors扮演。图中的箭头表示外键与主键之间的关系。例如,genres表中一行的movie_id列包含movies表中一行的id值。
movies和actors之间存在多对多的关系。通过使用roles表,将这种多对多的关系规范化为两个一对多的关系。roles表的每一行包含movies表和actors表的id字段的值。

Join types supported in ClickHouse
• INNER JOIN
• OUTER JOIN
• CROSS JOIN
• SEMI JOIN
• ANTI JOIN
• ANY JOIN
• ASOF JOIN

INNER JOIN
join2.png
内连接(INNER JOIN)对于每对在连接键上匹配的行,返回左表行的列值与右表行的列值的组合。如果一行有多个匹配项,则返回所有匹配项(这意味着对于具有匹配的连接键的行,会产生笛卡尔积)。
以下查询通过将movies表与genres表进行连接,找到每部电影的genre(s):
join3.png
请注意,可以省略INNER关键字。使用以下其他连接类型之一,可以扩展或更改INNER JOIN的行为。
图片 4.png
左外连接(LEFT OUTER JOIN)的行为类似于内连接(INNER JOIN),此外对于左表中的非匹配行,ClickHouse会返回右表列的默认值。
右外连接(RIGHT OUTER JOIN)查询类似于左外连接,它还返回右表中非匹配行的值,以及左表列的默认值。
全外连接(FULL OUTER JOIN)查询结合了左外连接和右外连接,它返回左表和右表中非匹配行的值,以及左表和右表列的默认值。
以下查询找出所有没有流派的电影,通过查询movies表中在genres表中没有匹配的所有行,因此在查询时,对于movie_id列会得到默认值0:
图片 5.png
Note that the OUTER keyword can be omitted.

CROSS JOIN
图片 6.png
交叉连接(CROSS JOIN)在不考虑连接键的情况下产生两个表的完全笛卡尔积。左表的每一行都与右表的每一行组合在一起。
因此,下面的查询将movies表的每一行与genres表的每一行组合在一起。
图片 7.png
虽然前面的示例查询本身并没有太多意义,但可以通过使用WHERE子句将匹配的行关联起来,来扩展查询,以实现查找每个movies的genre的内连接行为:
图片 8.png
图片 9.png
一个CROSS JOIN的另一种语法是在FROM子句中用逗号分隔的方式指定多个表。 如果查询的WHERE部分中存在连接表达式,ClickHouse会将CROSS JOIN重写为INNER JOIN。 我们可以通过EXPLAIN SYNTAX来检查示例查询是否符合这种情况(它返回查询在执行之前被重写的语法优化版本):
图片 10.png
在语法优化的交叉JOIN查询版本中,内部JOIN子句包含“ALL”关键字,该关键字是为了保持交叉JOIN的笛卡尔积语义,即使被重写为内部JOIN,因此笛卡尔积可以被禁用。
如上所述,可以省略外部连接,并且可以添加可选的所有关键字,你可以写所有的外部连接,它会正常工作。

(LEFT / RIGHT) SEMI JOIN
图片 11.png
左半连接(LEFT SEMI JOIN)查询返回左表中至少在右表中有一个连接键匹配的行的列值。只返回找到的第一个匹配项(禁用笛卡尔积)。
右半连接(RIGHT SEMI JOIN)查询类似,它返回右表中至少在左表中有一个匹配的行的值,但只返回找到的第一个匹配项。
以下查询找出在2023年参演过电影的所有演员/女演员。请注意,如果使用普通的(INNER)连接,同一个演员/女演员如果在2023年中扮演了多个角色,将会出现多次:
图片 12.png

(LEFT / RIGHT) ANTI JOIN
图片 13.png
左反连接(LEFT ANTI JOIN)返回左表中所有非匹配行的列值。
类似地,右反连接(RIGHT ANTI JOIN)返回右表中所有非匹配行的列值。
我们之前的外连接示例查询的另一种形式是使用反连接来查找数据集中没有genre的movie:
该查询使用左反连接将movies表的id与genres表的movie_id进行连接。它将返回movies表中所有没有与genres表匹配的行,即数据集中没有流派的电影的标题。这样,查询结果将只包含没有流派的电影的标题。
图片 14.png

(LEFT / RIGHT / INNER) ANY JOIN
图片 15.png
左任意连接(LEFT ANY JOIN)是左外连接(LEFT OUTER JOIN)和左半连接(LEFT SEMI JOIN)的组合,意味着ClickHouse将返回左表中每一行的列值,要么与右表中匹配行的列值组合,要么与右表的默认列值组合(如果没有匹配)。如果左表的一行在右表中有多个匹配项,ClickHouse只返回第一个匹配项的组合列值(禁用笛卡尔积)。
类似地,右任意连接(RIGHT ANY JOIN)是右外连接(RIGHT OUTER JOIN)和右半连接(RIGHT SEMI JOIN)的组合。
内任意连接(INNER ANY JOIN)是内连接(INNER JOIN)并禁用了笛卡尔积。
我们使用一个抽象示例和两个临时表(left_table和right_table)来演示左任意连接:
图片 16.png
This is the same query using a RIGHT ANY JOIN:
图片 17.png
This is the query with an INNER ANY JOIN:
图片 18.png

ASOF JOIN
图片 19.png
ASOF JOIN提供了非精确匹配的能力。如果左表中的一行在右表中没有精确匹配,那么将使用最接近的右表行作为匹配。
这在时间序列分析中非常有用,并可以大大降低查询的复杂性。
我们将以股票市场数据的时间序列分析为例。一个quotes表包含了基于每天特定时间的股票符号报价。在我们的示例数据中,价格每10秒更新一次。一个trades表列出了符号的交易 - 在特定时间买入的特定数量的符号:
图片 20.png
为了计算每笔交易的具体成本,我们需要将交易与其最接近的报价时间进行匹配。
使用ASOF JOIN,这个过程非常简单和紧凑,我们可以在ON子句中指定精确匹配条件,并在AND子句中指定最接近匹配条件 - 我们要寻找在交易日期之前或者正好等于交易日期的quotes表中的最接近行:
图片 21.png
图片 22.png

请注意,ASOF JOIN的ON子句是必需的,并且在AND子句的非精确匹配条件旁边指定了一个精确匹配条件。
目前,ClickHouse不支持没有任何连接键部分执行严格匹配的连接(尚未支持)。

Summary
这篇博客文章展示了ClickHouse如何支持所有标准的SQL JOIN类型,以及为支持分析查询而设计的专用JOIN类型。我们描述和演示了所有支持的JOIN类型。
在这个系列的下一部分中,我们将探讨ClickHouse如何将经典的JOIN算法与其查询管道相结合,以尽可能快地执行本文中描述的JOIN类型。

相关文章
|
存储 监控 OLAP
【ClickHouse 技术系列】- 在 ClickHouse 物化视图中使用 Join
本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机分析处理(OLAP)的开源分析引擎 ClickHouse,因其优良的查询性能,PB级的数据规模,简单的架构,被国内外公司广泛采用。本系列技术文章,将详细展开介绍 ClickHouse。
【ClickHouse 技术系列】- 在 ClickHouse 物化视图中使用 Join
|
2月前
|
存储 监控 分布式数据库
ClickHouse分布式数据库动态伸缩(弹性扩缩容)的实现
实现ClickHouse数据库的动态伸缩需要持续的维护和精细的操作。从集群配置到数据迁移,再到监控和自动化,每一步都要仔细管理以确保服务的可靠性和性能。这些活动可以显著提高应用的响应性和成本效率,帮助业务根据实际需求灵活调整资源分配。
168 10
|
4月前
|
关系型数据库 MySQL 定位技术
MySQL与Clickhouse数据库:探讨日期和时间的加法运算。
这一次的冒险就到这儿,期待你的再次加入,我们一起在数据库的世界中找寻下一个宝藏。
196 9
|
11月前
|
存储 关系型数据库 MySQL
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB区别,适用场景
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景比较
|
9月前
|
SQL Unix OLAP
ClickHouse安装教程:开启你的列式数据库之旅
ClickHouse 是一个高性能的列式数据库管理系统,适用于在线分析处理(OLAP)。本文介绍了 ClickHouse 的基本使用步骤,包括下载二进制文件、安装应用、启动服务器和客户端、创建表、插入数据以及查询新表。还提到了图形客户端 DBeaver 的使用,使操作更加直观。通过这些步骤,用户可以快速上手并利用 ClickHouse 的强大性能进行数据分析。
964 4
|
存储 SQL 缓存
数据库测试|Elasticsearch和ClickHouse的对决
由于目前市场上主流的数据库有许多,这次我们选择其中一个比较典型的Elasticsearch来和ClickHouse做一次实战测试,让大家更直观地看到真实的比对数据,从而对这两个数据库有更深入的了解,也就能理解为什么我们会选择ClickHouse。
数据库测试|Elasticsearch和ClickHouse的对决
|
11月前
|
存储 分布式计算 数据库
阿里云国际版设置数据库云分析工作负载的 ClickHouse 版
阿里云国际版设置数据库云分析工作负载的 ClickHouse 版
|
11月前
|
存储 关系型数据库 MySQL
四种数据库对比MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景
四种数据库对比 MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景
|
存储 消息中间件 弹性计算
统一观测丨借助 Prometheus 监控 ClickHouse 数据库
统一观测丨借助 Prometheus 监控 ClickHouse 数据库
1767 94
统一观测丨借助 Prometheus 监控 ClickHouse 数据库
|
DataWorks API 调度
DataWorks产品使用合集之在调度配置配置了节点的上游节点输出,没办法自动生成这个flow的依赖,该怎么操作
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
123 5

热门文章

最新文章

推荐镜像

更多