首页 > 编程知识 正文

clickhouse索引原理,clickhouse查询

时间:2023-05-04 02:06:30 阅读:12317 作者:2018

文章目录什么是clickhouse? 2 .分区和片2.1分区2.2片3 .分区相关操作3.1创建分区表3.2删除分区3.3查询分区信息4 .片原理5. clickhouse联合表查询5.1 Join查询现5.3 clickHouse分布式连接实现5.4数据预分布式co locate连接实现5.4

什么是clickhouse?

clickHouse访问指南和坑日记

clickHouse分区和分片详细信息

ClickHouse是面向在线分析处理(OLAP )的开源专栏存储的DBMS,简称CK,与Hadoop、Spark相比重量更轻,由俄罗斯首款搜索引擎Yandex于2016年6月发布

ClickHouse的特点:

开源列存储数据库管理系统。 支持线性扩展,简单方便,提高了高可靠性容错速度。 比Vertica快5倍,比Hive快279倍,比MySQL快800倍,可处理的数据级别达到10亿级别。 多功能:支持各种数据统计分析场景,支持类SQL查询,有关异地复制部署的具体介绍和安装教程,请参阅本文

点击house官方地址

clickhouse中文文档地址

2 .分区和分片2.1分区是表分区,是解决大数据存储的常见解决方案。 具体DDL操作的关键字是PARTITION BY,这意味着对一列中的每个数据(例如,日期)的表进行分区,最终将与不同分区对应的数据写入到不同的文件中。 功能类似于mysql索引,但主要是为了解决。 有时我们的查询只关心表中的一些数据。 创建表时引入了分区概念,这样就可以根据相应的分区字段找到相应的文件并显示查询。 这将防止查询扫描整个表内容,并将大量时间用于无谓的工作。

2.2切片clickhouse的切片。 实际上,它是一种对数据库分区进行复用的视图聚合功能,相当于在原始分区下,作为第2层分区显示在不同的节点/计算机上。 clickhouse支持读取每个分片上的内容集合。 基础是通过“分布式”的领导实现的。 默认情况下,您将随机写入某个分片,但您也可以自行指定并写入特定计算机。

分布式引擎官方网站介绍

分区和瓷砖的具体关系如下。

数据分区-如果指定了分区密钥,则查询可以最大限度地减少对数据的读取

数据片-允许多个计算机/节点同时执行查询,以实现分布式并行计算

3 .分区相关操作3.1分区表create table [ if not exists ] [ db.] table _ name [ onclustercluster ] [ name1[ type1] ] [ defaulule 物化| alias expr2] [ TTL expr2], INDEX index_name1 expr1 TYPE type1(. ) granularity index index _ name2expr2type type2(. ) GRANULARITY value2) engine=pr] )主king [ TTL expr [ delete|to disk ' XXX ' ], 3.2删除分区alter table [ db.] table _ namedroppartitionkey [ onclustercluster ] 3.3分区信息select * from system.partswwem ClickHouse提供了丰富的sharding战略,使业务能够根据实际需要进行选择。

1 ) random随机分片)写入数据随机分布在分布式集群内的某个节点上。

2 )常数固定分片)写入数据分发给固定节点。

3 ) column value分片)根据列中的值创建散列分片。

4 )自定义表达式分片)指定任意合法表达式,并根据计算出的值对表达式进行散列。

数据片使ClickHouse能够充分利用整个群集的大规模并行计算能力,并快速返回查询结果。

更重要的是,各种瓷砖功能打开了优化业务的想象力。 例如,在混叠的情况下,连接计算可以避免数据shuffle,直接在本地进行本地连接; 支持自定义sharding,为不同的业务和SQL Pattern定制最佳分片策略; 利用自定义sharding功能设置合理的sharding expressio

n可以解决分片间数据倾斜问题等。
另外,sharding机制使得ClickHouse可以横向线性拓展,构建大规模分布式集群,从而具备处理海量数据的能力。

不过ClickHouse的集群的水平拓展目前是一个瓶颈,因为历史数据的存在, 避免新增节点之后的数据倾斜是个难点。

5. clickhouse连表查询 5.1 Join 查询

我们都知道 Join 的常见连接类型分为以下几种:

INNER JOINOUTER JOINCROSS JOINSEMI JOINANTI JOIN

Join 的常见算法实现包含以下几种:

Nested Loop JoinSort Merge JoinHash Join

分布式系统实现 Join 数据分布的常见策略有:

Shuffle JoinBroadcast JoinColocate/Local Join

Colocate/Local Join 就是指多个节点 Join 时没有数据移动和网络传输,每个节点只在本地进行 Join,能够本地进行 Join 的前提是相同 Join Key 的数据分布在相同的节点。

5.2 clickHouse单机JOIN实现

ClickHouse 单机JOIN操作默认采用HASH JOIN算法,可选MERGE JOIN算法。其中,MERGE JOIN算法数据会溢出到磁盘,性能相比前者较差。

ClickHouse JOIN查询语法和mysql的join比较像,主要差别是global修饰符:

SELECT <expr_list>FROM <left_table>[GLOBAL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI|ANY|ASOF] JOIN <right_table>(ON <expr_list>)|(USING <column_list>) ...

ClickHouse 的 HASH JOIN算法实现逻辑大概如下:

从right_table 读取该表全量数据,在内存中构建HASH MAP;从left_table 分批读取数据,根据JOIN KEY到HASH MAP中进行查找,如果命中,则该数据作为JOIN的输出;

从这个实现中可以看出,如果right_table的数据量超过单机可用内存空间的限制,则JOIN操作无法完成。通常,两表JOIN时,将较小表作为right_table可以更好的提升性能。

5.3 clickHouse分布式JOIN实现

ClickHouse 的分布式JOIN查询可以分为两类,带GLOBAL关键字的,和不带GLOBAL关键字的情况,不带GLOBAL关键字的查询,每个节点都会全量去拉右表数据,然后和本地的左表进行关联匹配,存在查询放大的问题;加上GLOBAL关键字,initiator(作为计算协调者的节点)会先进行右表的查询,然后将结果发送给每个节点,再各个节点进行左表的关联匹配,避免了其他节点重复计算。所以,如果是分布式clickhouse集群,join查询建议使用GLOBAL修饰。

比如下面这条sql,针对是否带GLOBAL关键字的执行步骤分别如下:

SELECT a_.i, a_.s, b_.t FROM a_all as a_ JOIN b_all AS b_ ON a_.i = b_.i其中,a_all, b_all为分布式表,对应的本地表名为a_local, b_local

无GLOBAL关键字的JOIN实现:

initiator 收到查询请求

initiator 执行分布式查询,本节点和其他节点执行SELECT a_.i, a_.s, b_.t FROM a_local AS a_ JOIN b_all as b_ ON a_.i = b_.i即左表分布式表更改为本地表名。该SQL在集群范围内并行执行。

集群节点收到2)中SQL后,分析出右表时分布式表,则触发一次分布式查询:SELECT b_.i, b_.t FROM b_local AS b_ 集群各节点并发执行,并合并结果,记为subquery.

集群节点完成3)中SQL执行后,执行 SELECT a_.i, a_.s, b_.t FROM a_local AS a_ JOIN subquery as b_ ON a_.i = b_.i其中subquery表示2中执行的结果

各节点执行完成JOIN计算后,向initiator节点发送数据

GLOBAL JOIN 计算过程如下:

initiator 收到查询请求

initiator 和集群其他节点均执行SELECT b_.i, b_.t FROM b_local AS b_ 即左表分布式表更改为本地表名。该SQL在集群范围内并行执行。汇总结果,记录为subquery。

initiator 将2)中subquery发送到集群中其他节点,并触发分布式查询:SELECT a_.i, a_.s, b_.t FROM a_local AS a_ JOIN subquery as b_ ON a_.i = b_.i其中subquery表示2)中执行的结果

各节点执行完成JOIN计算后,向initiator节点发送数据

5.4 数据预分布实现Colocate JOIN

写入数据时,不采用random随机分片的方式,而是通过select * from system.cluster获取集群的列表,然后针对JOIN KEY和集群内机器列表,进行hash的方式,将相同的JOIN KEY的数据写到同一个节点上,这样可以将分布式JOIN转为为节点的本地JOIN,极大减少了查询放大问题。

如果如下操作:

将涉及JOIN的表按JOIN KEY分片,保证相同的JOIN KEY的数据在同一个节点上

修改sql,将JOIN中右表换成相应的本地表,针对上面的示例sql,则修改为如下:

SELECT a_.i, a_.s, b_.t FROM a_all as a_ JOIN b_local AS b_ ON a_.i = b_.i

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。