在 UNION 查询中执行 DISTRIBUTE BY 时是不是需要子查询?

Posted

技术标签:

【中文标题】在 UNION 查询中执行 DISTRIBUTE BY 时是不是需要子查询?【英文标题】:Do I need a subquery when doing DISTRIBUTE BY in a UNION query?在 UNION 查询中执行 DISTRIBUTE BY 时是否需要子查询? 【发布时间】:2020-06-22 18:08:08 【问题描述】:

考虑:

select 1 as id, 2 as val

UNION ALL

select 2 as id, 1 as val

DISTRIBUTE BY id SORT BY val

DISTRIBUTE BY 是否仅适用于第二个 select 表,还是适用于 UNION ALL 的结果,这有点模棱两可。

我是否需要一个子查询来确保 DISTRIBUTE 步骤仅在 UNION ALL 完成后应用,即

select * from (
  select 1 as id, 2 as val
  union all
  select 2 as id, 1 as val
)
DISTRIBUTE BY id SORT BY val

两个查询的EXPLAIN 看起来相同:

== Physical Plan ==
*(3) Sort [val#636 ASC NULLS FIRST], false, 0
+- Exchange hashpartitioning(id#635, 200)
   +- Union
      :- *(1) Project [1 AS id#635, 2 AS val#636]
      :  +- Scan OneRowRelation[]
      +- *(2) Project [2 AS id#637, 1 AS val#638]
         +- Scan OneRowRelation[]

但我不清楚对于更复杂的查询是否总是如此(在我尝试过的更实际的用例中,一列的列别名 # 存在细微差别)

【问题讨论】:

【参考方案1】:

来自the Hive docs:

将 ORDER BY、SORT BY、CLUSTER BY、DISTRIBUTE BY 或 LIMIT 应用于 单独的 SELECT,将子句放在括号内 附上 SELECT:

SELECT key FROM (SELECT key FROM src ORDER BY key LIMIT 10) subq1 
UNION
SELECT key FROM (SELECT key FROM src1 ORDER BY key LIMIT 10) subq2

应用 ORDER BY、SORT BY、CLUSTER BY、DISTRIBUTE BY 或 LIMIT 子句到整个 UNION 结果,放置 ORDER BY、SORT BY、 最后一个之后的 CLUSTER BY、DISTRIBUTE BY 或 LIMIT。

以下 示例同时使用 ORDER BY 和 LIMIT 子句:

SELECT key FROM src
UNION 
SELECT key FROM src1  
ORDER BY key LIMIT 10 

因此,在您的情况下,DISTRIBUTE BY 子句将应用于 UNION 的整个结果。

【讨论】:

以上是关于在 UNION 查询中执行 DISTRIBUTE BY 时是不是需要子查询?的主要内容,如果未能解决你的问题,请参考以下文章

SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用

是否可以在 Postgres 中执行并行查询,使用 union all 查询分区表?

UVA11987--Almost Union-Find

SQL学习之组合查询(UNION)

MySQL ----- 组合查询 UNION(十五)

MySQL ----- 组合查询 UNION(十五)