ClickHouse的join优化

news2024/11/28 6:46:16

概要:

ClickHouse 最为擅长的领域是一个大宽表来进行查询,多表 JOIN 时Clickhouse 性能表现不佳。

CK执行模式

第一阶段,Coordinator 收到查询后将请求发送给对应的 worker 节点;第二阶段,Coordinator 收到各个 worker 节点的结果后汇聚起来处理后返回。

来源:ClickHouse Join为什么被大家诟病? - 知乎

优化建议

 用IN代替JOIN

JOIN 需要基于内存构建 hash table 且需要存储右表全部的数据,然后再去匹配左表的数据。而 IN 查询会对右表的全部数据构建 hash set,但是不需要匹配左表的数据,且不需要回写数据到block。

SELECT event_date,
         count()
FROM tob_apps_all
WHERE app_id = 10000000
        AND event_date >= '2022-01-01'
        AND event_date <= '2022-08-02'
        AND hash_uid global IN 
    (SELECT hash_uid
    FROM users_unique_all
    WHERE (tea_app_id = 10000000)
            AND (last_active_date >= '2022-01-01') )
 GROUP BY event_date

优先本地join

数据预先相同规则分区,也就是 Colocate JOIN。优先将需要关联的表按照相同的规则进行分布,查询时就不需要分布式的 JOIN。

SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
ANY LEFT JOIN 
(
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1

 比如事件表 tob_apps_all 和用户表 users_unique_all 都是按照用户 ID 来分 shard 存储的,相同的用户的两个表的数据都在同一个 shard 上,因此这两个表的 JOIN 就不需要分布式 JOIN 了。

来源:ClickHouse 引擎在行为分析场景下的 JOIN 优化 - 简书

引擎层优化

Join 表引擎可以说是为 JOIN 查询而生的,它等同于将 JOIN 查询进行了一层简单封装。

说明:
需要说明的是:Join表引擎更加通常的用途,是用于Join连接查询的右侧表。且Join表的数据是首先被写至内存,然后才被同步到磁盘文件上。这意味着两件事:
1.Join表的查询速度很快,因为它的存在本来就是为了优化连接查询的速度;
2.Join表不适合存放千万级以上的大表,否则会占用过多的服务器内存,它更适合存放需要经常查询的小表,且通常为join语句的右侧表。

Join(ANY|ALL, LEFT|INNER, k1[, k2, ...])

引擎参数:ANY|ALL – 连接修饰;LEFT|INNER – 连接类型。更多信息可参考 JOIN子句。
这些参数设置不用带引号,但必须与要 JOIN 表匹配。 k1,k2,……是 USING 子句中要用于连接的关键列。

此引擎表不能用于 GLOBAL JOIN 。

类似于 Set 引擎,可以使用 INSERT 向表中添加数据。设置为 ANY 时,重复键的数据会被忽略(仅一条用于连接)。设置为 ALL 时,重复键的数据都会用于连接。不能直接对 JOIN 表进行 SELECT。检索其数据的唯一方法是将其作为 JOIN 语句右边的表。

跟 Set 引擎类似,Join 引擎把数据存储在磁盘中。

创建基于join引擎的表

数据表

CREATE TABLE join_tb1 (
id UInt8,
name String,
time Datetime
) ENGINE = Log

join表

CREATE TABLE id_join_tb1 (
id UInt8,
price UInt32,
time Datetime
) ENGINE = Join (ANY, LEFT, id);

插入测试数据

INSERT INTO TABLE join_tb1 VALUES 
(1,'ClickHouse','2019-05-01 12:00:00'),   
(2,'Spark', '2019-05-01 12:30:00'), 
(3,'ElasticSearch','2019-05-01 13:00:00');

INSERT INTO TABLE id_join_tb1 VALUES 
(1,100,'2019-05-01 11:55:00'),
(1,105,'2019-05-01 11:10:00'),
(2,90,'2019-05-01 12:01:00'),
(3,80,'2019-05-01 13:10:00'),
(5,70,'2019-05-01 14:00:00'),
(6,60,'2019-05-01 13:50:00');

join查询

#这段的意思是数据表 join_tb1 用id字段  关联join表 id_join_tb1 关联出 id_join_tb1的price字段。

SELECT id,name,joinGet ('id_join_tb1', 'price', id) as  price 
FROM join_tb1 ;

取特定某条

SELECT joinGet ('id_join_tb1', 'price', toUInt8 (1));

来源:Join Table Engine | ClickHouse Docs

创建基于join引擎的视图

创建数据表

drop table if exists user_order;
create table user_order
(    
    user_id String,         // 用户ID
    event_date String,      // 付款日期
    order_no String,        // 订单号
    amount Int32            // 金额
) ENGINE = MergeTree()
ORDER BY (user_id, event_date)

创建视图

drop view if exists user_order_userid_j;
CREATE MATERIALIZED VIEW user_order_userid_j
ENGINE = Join(ANY, INNER, user_id)
POPULATE
AS
select user_id, event_date, order_no, amount
from user_order

插入数据

insert into user_order(user_id, event_date, order_no, amount)
values
('user1', '2022-01-01', 'B', 4),
('user1', '2022-01-01', 'C', 8),
('user1', '2022-01-01', 'A', 2),
('user2', '2022-01-02', 'E', 3),
('user2', '2022-01-02', 'D', 7),
('user1', '2022-01-02', 'X', 6),
('user1', '2022-01-02', 'Y', 9)   

join查询

select * from user_order_userid_j

来源:

clickhouse中使用Join表引擎 - 技术 - 张子阳的博客

ClickHouse学习笔记(二):ClickHouse常见表引擎简介_clickhouse url格式_leo825...的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/607630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java内存模型和常见的内存溢出类型及解决方案

Java内存模型与常见的内存溢出 一. Java 运行过程和内存分配1 Java的平台无关性2 Java内存模型2.1Java内存模型图 3 内存结构详解3.1 元空间&#xff08;MetaSpace&#xff09;3.2 堆区&#xff08;Heap&#xff09;新生代老年代 3.3 虚拟机栈&#xff08;VM Stack&#xff09;…

Linux :: vim 编辑器:详解:光标移动定位内容,行间:快速定位至文本:开头 / 结尾;行内:词间跳跃

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 前言&#x…

Asana替代方案推荐:盘点2023年8种优质的免费和付费替代工具

Asana是一个项目管理和团队合作软件平台&#xff0c;自2008年成立以来&#xff0c;一直在彻底改变团队合作的方式。Asana以其直观的用户界面而闻名&#xff0c;是项目经理和团队领导的热门选择。然而在快节奏的项目管理世界中&#xff0c;技术发展很快。因此&#xff0c;当涉及…

chatgpt赋能python:Python取余方法介绍

Python取余方法介绍 在Python编程中&#xff0c;取余&#xff08;也称为求模运算或取模运算&#xff09;是计算机程序经常使用的一种基本算术运算。Python提供了两种方法来执行取余运算&#xff1a;使用百分号符号&#xff08;%&#xff09;和divmod()函数。 使用百分号符号&…

揭秘HTTP代理的神奇力量:让你的系统突破内网限制

大家好&#xff0c;我是你们的小米&#xff01;今天&#xff0c;我要和大家聊聊一个技术问题&#xff0c;那就是关于"http代理"的使用。昨日&#xff0c;我刚刚午休睡醒&#xff0c;项目经理杰哥叫我关注下其中一个项目的部署进展情况。而就在这时&#xff0c;客户侧…

15天学会EasyX 第2天:EasyX里的设备坐标与打开关闭绘图窗口

本文为山城瑞宝创作&#xff0c;转载请标注版权&#xff01; 本文里的函数使用都不需要先写明原型&#xff0c;原型就在其对应的库里&#xff08;直接用&#xff09; 目录 1. 设备及其坐标 2. 如何打开与关闭绘图窗口 2.1. initgraph 2.1.1. 没有flag的代码示例 2.1.2. 使用了…

会声会影2023旗舰中文试用版下载安装教程

会声会影2023版(Corel VideoStudio)是一款专业视频制作软件及视频剪辑软件,可以剪辑合并视频,制作视频,屏幕录制,光盘制作,视频后期编辑,添加特效,字幕和配音等操作,界面美观,素材丰富,操作简洁而! 会声会影有多轨道式编辑功能&#xff0c;可以独立处理视频、图片、音频等素材&…

MATLAB笔记总结(1) 东华大学MOOC

循环语句 MATLAB函数句柄 https://zhuanlan.zhihu.com/p/266263265 https://blog.csdn.net/shaozheng0503/article/details/130305984?spm1001.2014.3001.5501 数据和变量 表达式 分号;) 逗号(, ), 省略号(3个英文句点…)。 历史指令调用&#xff1a;用方向键(↑↓) 数据…

离散分类和非离散分类问题中的模型评价

离散分类问题中的模型评价 假设分类目标只有两类&#xff1a;正样本&#xff08;positive&#xff09;和负样本&#xff08;negative&#xff09;。 分类器的分类结果会出现以下四种情况&#xff1a; TP: 若一个实例为正&#xff0c;且被预测为正&#xff0c;即为“真正类”(…

chatgpt赋能python:Python去空格输出:优化您的代码和网站速度

Python去空格输出&#xff1a;优化您的代码和网站速度 Python是一种简单易用的编程语言&#xff0c;广泛用于各种应用和网站开发。然而&#xff0c;Python的代码输出&#xff08;如HTML和CSS&#xff09;中不可避免地包含了空格、制表符和换行符。这些额外的字符可能会影响网站…

模式识别算法的常见评价指标TP/FP/FN/TN,ROC,DET,EER

文章目录 TP/FP/FN/TN&#xff08;TA/FA/FR/TR&#xff09;误报率&#xff08;FAR&#xff09;漏报率&#xff08;FRR&#xff09; ROC曲线&#xff08;Receiver Operating Characteristic Curve&#xff0c;受试者特征曲线&#xff09;DET曲线&#xff08;Detection Error Tra…

Maven高级——继承与聚合——版本锁定

在前面的文章已经实现了Maven的继承&#xff0c;初次之外&#xff0c;还可以在父工程当中统一管理依赖的版本。 场景介绍 有一些依赖不是各个模块共有的&#xff0c;则需要到那些子模块当中单独配置了&#xff0c;这时需要到各个模块单独配置了&#xff0c;比如下图有一个模块…

【小沐学Python】Python实现Web服务器(CentOS+Docker下部署Flask)

&#x1f37a;基于Python的Web服务器系列相关文章编写如下&#x1f37a;&#xff1a; &#x1f388;【Web开发】Python实现Web服务器&#xff08;Flask快速入门&#xff09;&#x1f388;&#x1f388;【Web开发】Python实现Web服务器&#xff08;Flask案例测试&#xff09;&a…

Pyside6-第五篇-单选按钮QRadioButton

今天是Pyside6的第五篇内容。一起来看单选按钮。 QRadioButton。 class QRadioButton(QAbstractButton):"""QRadioButton(self, parent: Optional[PySide6.QtWidgets.QWidget] None) -> NoneQRadioButton(self, text: str, parent: Optional[PySide6.QtWidg…

9.wxss

wxss基本满足所有css&#xff0c;并在css的基础上增加了 rpx 尺寸单位import 导入样式 目录 1 rpx 2 import 3 全局样式与局部样式 4 样式权重 1 rpx rpx(responsive pixel)&#xff0c;中文名叫响应像素&#xff0c;它是用来解决屏幕适配的尺寸单位&#xff0c;它…

Flink第九章:Flink CEP

系列文章目录 Flink第一章:环境搭建 Flink第二章:基本操作. Flink第三章:基本操作(二) Flink第四章:水位线和窗口 Flink第五章:处理函数 Flink第六章:多流操作 Flink第七章:状态编程 Flink第八章:FlinkSQL Flink第九章:Flink CEP 文章目录 系列文章目录前言一、简单案例1.Logi…

Linux高性能服务器编程|阅读笔记:第11章 - 定时器

目录 简介系列笔记11.1 socket选项SO_RCVTIMEO和SO_SNDTIMEO11.2 SIGALRM信号11.2.1 基于升序链表的定时器11.2.2 处理非活动连接11.3 I/O复用系统调用的超时参数11.4 高性能定时器11.4.1 时间轮11.4.2 时间堆结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方…

光储存技术及原理

描述 信息资料迅速增长是当今社会的一大特点。有人统计&#xff0c;科技文献数量大约每7年增加1倍&#xff0c;而一般的情报资料则以每2年~3年翻一番的速度增加。大量资料的存储、分析、检索和传播&#xff0c;迫切需要高密度、大容量的存储介质和管理系统。 1898年荷兰的Vald…

Jenkins+Docker 实现一键自动化部署项目!步骤齐全,少走坑路

本文章实现最简单全面的Jenkinsdockerspringboot 一键自动部署项目&#xff0c;步骤齐全&#xff0c;少走坑路。 环境&#xff1a;centos7git(gitee) 简述实现步骤&#xff1a;在docker安装jenkins&#xff0c;配置jenkins基本信息&#xff0c;利用Dockerfile和shell脚本实现…

javaScript蓝桥杯-----芝麻开门

目录 一、介绍二、准备三、目标四、代码五、完成 一、介绍 在阿里巴巴和四十大盗的故事中&#xff0c;阿里巴巴因为无意中知道了开门的咒语人生发生了翻天覆地的变化&#xff0c;四十大盗也因为咒语的泄露最终丧命。芝麻开门的咒语作为重要的信息推动着故事的发展。下面由你来…