clickhouse 子查询_Clickhouse 查询分布式表子查询 (Distributed Subqueries )
官方文檔:https://clickhouse.tech/docs/en/sql-reference/operators/in/#select-distributed-subqueries
在分布式表上執(zhí)行in/join等子查詢的時(shí)候建議使用global in或global
joins,直接使用普通的in/join可能有數(shù)據(jù)正確性的問(wèn)題,直接使用 in 在分布式表又可能導(dǎo)致性能問(wèn)題。
如我們有3臺(tái)服務(wù)器,每臺(tái)服務(wù)器上有一張叫l(wèi)ocal_table的表,另外還有一張分布式表distribute_table指向這個(gè)loacl_table表。
case1:
在server1上提交查詢sql1:
SELECT uniq(UserID) FROM distributed_table
實(shí)際上sq1將被翻譯成如下在3臺(tái)服務(wù)器上執(zhí)行,執(zhí)行完成將結(jié)果匯總給到server1上合并,然后在返回給用
SELECT uniq(UserID) FROM local_table
case2:
在server1上提交查詢sql2:帶子查詢
SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34)
實(shí)際上sq1將被翻譯成如下sql在3臺(tái)服務(wù)器上執(zhí)行,執(zhí)行完成將結(jié)果匯總給到server1上合并,然后在返回給用
SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34)
這種情況數(shù)據(jù)可能會(huì)是錯(cuò)誤的,因?yàn)槊總€(gè)server上的userId都只有自己服務(wù)器上的serverID,如:server1上有userid:1,2 ;server2上有userId:3,4,5,server3上有userId:6,7,8。本來(lái)應(yīng)該在每個(gè)local上的 userid in(1,2,3,4,5,6,7,8) ,但是現(xiàn)在只是分別在1上in(1,2),server2上in(3,4,5),server3上in(6,7,8),結(jié)果很可能就錯(cuò)誤了。
在server1上提交查詢Sql3:帶子查詢但是從分布式表查詢
SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34)
實(shí)際上sq1將被翻譯成如下sql在3臺(tái)服務(wù)器上執(zhí)行,但是執(zhí)行的時(shí)候發(fā)現(xiàn)有distributed_table,然后又從每臺(tái)機(jī)器上把這個(gè)子查詢發(fā)給3臺(tái)server查詢
SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34)
發(fā)給3臺(tái)的子查詢
SELECT UserID FROM local_table WHERE CounterID = 34
這樣相當(dāng)于這樣一個(gè)查詢要執(zhí)行n*n次,n為服務(wù)器數(shù)量,這個(gè)性能會(huì)非常低下。
在server1上提交查詢Sql3:帶子查詢使用global in
SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34)
此時(shí)server1將會(huì)提交一個(gè)子查詢
SELECT UserID FROM distributed_table WHERE CounterID = 34
然后在3臺(tái)服務(wù)器上執(zhí)行如下sql,然后將結(jié)果返回給server1結(jié)果將會(huì)在內(nèi)存中保存一張臨時(shí)表
SELECT UserID FROM local_table WHERE CounterID = 34
然后從server1發(fā)出整個(gè)sql查詢
SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1
這樣整個(gè)查詢可能只需要執(zhí)行n*2次,比之前要少很多倍。
注意:
1、使用global in 查詢時(shí)返回的子查詢結(jié)果是不去重的,所有數(shù)據(jù)都會(huì)保存到內(nèi)存臨時(shí)表中然后發(fā)送給各個(gè)server進(jìn)行整個(gè)sql查詢,這樣可能會(huì)導(dǎo)致數(shù)據(jù)量和網(wǎng)絡(luò)浪費(fèi),在查詢時(shí)可以指定distinct,普通的in查詢沒(méi)有這個(gè)問(wèn)題。
2、同時(shí)拷貝數(shù)據(jù)到其他節(jié)點(diǎn)去執(zhí)行查詢時(shí),沒(méi)有網(wǎng)絡(luò)帶寬流量的限制,可能導(dǎo)致網(wǎng)絡(luò)資源進(jìn)展。
總結(jié)
以上是生活随笔為你收集整理的clickhouse 子查询_Clickhouse 查询分布式表子查询 (Distributed Subqueries )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: flash如何制作影子效果
- 下一篇: Flash制作一个简单的按钮