ClickHouse中arrayJoin与GROUP BY使用困惑及执行顺序问询
ClickHouse中arrayJoin与GROUP BY的执行顺序问题
第一条SQL及执行结果
SELECT rtx , arrayJoin(['Istanbul', 'Berlin', 'Bobruisk']) AS city FROM ( SELECT 'hi' as rtx ) where city = 'Istanbul' group by rtx, city;
执行结果:
| rtx | city |
|---|---|
| hi | Istanbul |
第二条SQL及执行结果
SELECT rtx , arrayJoin(['Istanbul', 'Berlin', 'Bobruisk']) AS city FROM ( SELECT 'hi' as rtx ) where city = 'Istanbul' group by rtx;
执行结果:
| rtx | city |
|---|---|
| hi | Istanbul |
| hi | Berlin |
| hi | Bobruisk |
核心问题解析:执行顺序拆解
第二条SQL的结果看似反常,本质是ClickHouse对arrayJoin的处理逻辑和常规SQL存在差异,具体执行步骤如下:
- 第一步:处理FROM与WHERE条件(触发第一次隐式arrayJoin)
- 先执行子查询获取
rtx='hi'的单行数据。 - 由于WHERE子句引用了由
arrayJoin生成的city列,ClickHouse会先对这行数据执行一次arrayJoin,将其展开为3行:(hi, Istanbul)、(hi, Berlin)、(hi, Bobruisk)。 - 应用
WHERE city = 'Istanbul'过滤后,仅剩下1行数据:(hi, Istanbul)。
- 先执行子查询获取
- 第二步:执行GROUP BY分组
- 按照
rtx分组,此时分组后仅得到1组数据:rtx='hi'。
- 按照
- 第三步:执行SELECT子句中的arrayJoin(第二次显式执行)
- 对分组后的每组数据(这里仅1组),再次执行
arrayJoin(['Istanbul', 'Berlin', 'Bobruisk']),重新将单行数据展开为3行,这就是最终返回的结果。
- 对分组后的每组数据(这里仅1组),再次执行
简单来说:WHERE里的city引用会触发一次隐式的arrayJoin来过滤数据,而SELECT里的arrayJoin是在GROUP BY完成后再次执行的,所以最终看起来像是执行了两次arrayJoin。
内容的提问来源于stack exchange,提问作者Yuanchao Hu
相关产品推荐
相关产品推荐

