Clickhouse 分布式子查询——global in/join(慎用慎用)

@羲凡——只为了更好的活着

Clickhouse 分布式子查询——global in/join(慎用慎用)

不能一味的追求查询效率,将分布式子查询都改成global in,一定要结合业务逻辑

假设:有一个分布式表,字段班级、姓名、年龄,ck集群有两个分片,查询103班级年龄10岁的人

classnameage
102EEE10
102GGG10
103DDD8
103BBB9
103AAA10
103CCC10
103GGG11
1、建表语句
CREATE TABLE test_db.staff_replica ON CLUSTER your_ck_cluster
(
    class		UInt8
	,name     	LowCardinality(FixedString(3))
	,age        UInt8
)
ENGINE=ReplicatedMergeTree('/clickhouse/tables/{shard}/{database}/{table}', '{replica}')
ORDER BY (class ,name ,age );

CREATE TABLE test_db.staff_all ON CLUSTER your_ck_cluster
AS test_db.staff_replica
ENGINE = Distributed(your_ck_cluster, test_db, staff_replica, rand());
2、数据分别插入两个分片
--插入分片A
insert into staff_replica values(103,'AAA',10),(103,'BBB',9),(103,'GGG',11);
--插入分片B
insert into staff_replica values(103,'CCC',10),(103,'DDD',8),(102,'GGG',10),(102,'EEE',10);
3、查询sql
--普通 in
select * from test_db.staff_all 
where age=10 and name in (select name from test_db.staff_all a where class=103) ;
--global in
select * from test_db.staff_all 
where age=10 and name global in (select name from test_db.staff_all a where class=103) ;
--普通 join
select a.* from test_db.staff_all a 
join (select name from test_db.staff_all a where class=103) b on a.name=b.name
where a.age=10  ;
--global join
select a.* from test_db.staff_all a global 
join (select name from test_db.staff_all a where class=103) b on a.name=b.name
where a.age=10  ;
4、结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问:用 global in/join, 为啥102班级的GGG同学也被筛选出来了?

答:分布式子查询在使用global in/join 是sql的执行顺序和in不一样

下面以global in为例,global join的情况也是一样的
a.普通in的执行情况
-- 1.将下面的查询分发到每个分片机器上执行
select * from test_db.staff_replica 
where age=10 and name in (select name from test_db.staff_all a where class=103) ;
--2.将上sql中分布式子查询再拆成本地表,在每台机器上查询
select name from test_db.staff_replica a where class=103
--3.说白了就是将下面的语句执行了n的平方次,n为分片的数量
select * from test_db.staff_replica 
where age=10 and name in (select name from test_db.staff_replica a where class=103) ;
b.global in的执行情况
-- 1.select name from test_db.staff_all a where class=103 的结果存在RAM中的临时表,比如 _data1
--2.将数据_data1和下面的sql请求将被发送到每个执行服务器
select * from test_db.staff_all where age=10 and name global in _data1
语言表达有限,没看懂的可以看一下 官网 关于global in/join的解释

|
|
|

====================================================================

@羲凡——只为了更好的活着

若对博客中有任何问题,欢迎留言交流

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值