clickhouse的global in/join 和普通的in/join的區別


總結轉載

 

 

https://clickhouse.tech/docs/zh/sql-reference/operators/in/#select-distributed-subqueries

SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34)
這條語句不使用global in 的話 前面一段查到一個UserID就會跑到子查詢里面看in不in 子查詢是分布式的 就會接收到這個查詢請求之后下發到每個本地表 比如前面的UserID有n個 分布的本地表有n個 那么復雜度就是 n^2

 

但是用了global in 之后 就會將子查詢符合條件的UserID全部查出來之后放到內存做臨時表 一次性全部分發給請求的各個節點的本地表執行前面那段 查出符合條件的數據 請求的復雜度就只有n了 

 

所以使用global的前提條件就是左表是分布式表,右表是小表

 

備注:

SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) 該語句時會向集群各個節點發送 SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) 這樣的查詢請求,復雜度是n

 

使用注意:

  • 創建臨時表時,數據不是唯一的,為了減少通過網絡傳輸的數據量,請在子查詢中使用DISTINCT(你不需要在普通的IN中這么做)
  • 臨時表將發送到所有遠程服務器。其中傳輸不考慮網絡的拓撲結構。例如,如果你有10個遠程服務器存在與請求服務器非常遠的數據中心中,則數據將通過通道發送數據到遠程數據中心10次。使用GLOBAL IN時應避免大數據集。
  • 當使用global…JOIN,首先會在請求者服務器運行一個子查詢來計右表(right table)。將此臨時表傳遞給每個遠程服務器,並使用傳輸的臨時數據在其上運行查詢。會出現網絡傳輸,因此盡量將小表放在右表。

 

 

https://blog.csdn.net/weixin_42003671/article/details/116533735

這個例子說明了 分布式子查詢在使用global in/join 是sql的執行順序和in不一樣

普通的是按照執行順序查出符合條件的數據,例子中的 'GGG' 存在重復的數據,在普通的in/join中會篩選符合子查詢和where條件的數據

使用了global之后,會先選出符合子查詢條件的數據,然后再根據where的判斷條件曬出數據,這個時候一條  'GGG' 符合子查詢條件,篩出來之后在分布式表中存在一條滿足where條件,這就會被選出來,但是這條數據並不同時滿足where條件和子查詢條件,普通的就不會查出來。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM