记一次clickhouse查询问题Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = ‘deny‘)
最近在工作中使用到了clickhouse,在查詢數據統計的時候遇到了一點問題,后來解決了,記錄一下
ClickHouse是一個用于聯機分析(OLAP)的列式數據庫管理系統–DBMS ( 來自不同列的值被單獨存儲,來自同一列的數據被存儲在一起 )
適用于大多數是讀請求,數據較少更新或者沒有更新的場景。clickhouse的一大優點是支持SQL, 在查詢的學習成本上低于es.
SQL格式如下:
[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list [FROM [db.]table | (subquery) | table_function] [FINAL] [SAMPLE sample_coeff] [ARRAY JOIN ...] [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [PREWHERE expr] [WHERE expr] [GROUP BY expr_list] [WITH TOTALS] [HAVING expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [LIMIT [offset_value, ]n BY columns] [LIMIT [n, ]m] [WITH TIES] [UNION ALL ...] [INTO OUTFILE filename] [FORMAT format]業務場景:
一批數據周期調用某個接口,每次調用的結果都會記錄下來,想按照周期來統計該數據的調用結果。
每個周期內數據的唯一id是businessId,在同一周期內相同businessId的數據保留最新的一條作為統計數據源
SQL:對指定周期內的數據,統計其最新的business信息
SELECT * FROM db.t_data t1 inner join (SELECT businessId , max(lastchangetime) lasttime FROM db.t_data where lastchangetime >= toDateTime('?') and lastchangetime <= toDateTime('?') and businessId >= ? and businessId <=? group by businessId) t2 on t1.businessId = t2.businessId and t1.lastchangetime = t2.lasttime這個sql在MySQL執行是OK的,但是在clickhouse執行會報如下錯誤:"syntax error, expect {, actual error, pos 1, line 1, column 2Code: 288, e.displayText() = DB::Exception: Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = 'deny'). You may rewrite query to use local tables in subqueries, or use GLOBAL keyword, or set distributed_product_mode to suitable value. (version 20.1.4.14 (official build))\n"
根據報錯信息,因為不支持分布式子查詢而發生如上報錯,建議是在子查詢里使用本地表或者使用GLOBAL, 我將inner join 改為global join 就沒有報錯了
那么clickhouse的分布式查詢又是怎么一回事呢?
帶子查詢的IN-s有兩個選項(類似于連接):normal IN / JOIN 和 GLOBAL IN / GLOBAL JOIN. 它們在分布式查詢處理的運行方式上有所不同。
當使用常規IN時,查詢被發送到遠程服務器,并且它們中的每個服務器都在運行子查詢 IN 或JOIN 條款
使用 GLOBAL IN / GLOBAL JOINs時,首先所有的子查詢都運行 GLOBAL IN / GLOBAL
JOINs,并將結果收集在臨時表中。 然后將臨時表發送到每個遠程服務器,其中使用此臨時數據運行查詢。
分布式子查詢主要是用于在連接查詢時,如果關聯的數據分散在不同的集群中,那么子查詢就需要先在所有集群節點上查詢,然后以其并集作為子查詢的結果集,否則查詢出來的結果不準確。為了提高效率,官方是推薦使用global join(將 GLOBAL 修飾的子句,單獨進行了一次分布式查詢, 子查詢的結果合并后存儲在臨時表中)代替普通的join。
參考資料:
ClickHouse概述
ClickHouse分布式IN & JOIN 查詢的避坑指南
house.tech/docs/zh/sql-reference/operators/in/
總結
以上是生活随笔為你收集整理的记一次clickhouse查询问题Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = ‘deny‘)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何优雅的设计和使用缓存?
- 下一篇: maven打包的各种方式和如何在使用ma