Hive - 如何在hive中重用子查询以获得最佳性能

问题描述 投票:1回答:1

当我有一个在整个select语句中重复多次的复杂子查询时,在Hive中构造/编写查询的最佳方法是什么?

我最初为子查询创建了一个临时表,在每次运行之前刷新了该表。然后我开始使用CTE作为原始查询的一部分(丢弃临时表)以提高可读性并注意到性能下降。这使我对在需要重用子查询时性能方面最佳的实现方法感到好奇。

我正在使用的数据包含超过1000万条记录。下面是我编写的使用CTE的查询示例。

with temp as (
   select
      a.id,
      x.type,
      y.response
   from sandbox.tbl_form a
   left outer join sandbox.tbl_formStatus b
   on a.id = b.id
   left outer join sandbox.tbl_formResponse y
   on b.id = y.id
   left outer join sandbox.tbl_formType x
   on y.id = x.typeId
   where b.status = 'Completed'
)
select
   a.id,
   q.response as user,
   r.response as system,
   s.response as agent,
   t.response as owner
from sandbox.tbl_form a
left outer join (
   select * from temp x
   where x.type= 'User'
) q
on a.id = q.id
left outer join (
   select * from temp x
   where x.type= 'System'
) r
on a.id = r.id
left outer join (
   select * from temp x
   where x.type= 'Agent'
) s
on a.id = s.id
left outer join (
   select * from temp x
   where x.type= 'Owner'
) t
on a.id = t.id;
performance view hive subquery common-table-expression
1个回答
3
投票

您的查询中存在问题。

1)在CTE中,您有三个没有ON子句的左连接。这可能会导致严重的性能问题,因为没有ON子句的连接是CROSS JOINS。

2)BTW where b.status = 'Completed'子句将表b的LEFT连接转换为内部连接,但仍然没有ON子句它将所有记录从b乘以where中的所有记录。

3)很可能你根本不需要CTE。只需正确加入ON子句并使用case when type='User' then response end + min()使用max()id汇总:

select a.id
max(case when x.type='User' then y.response end) as user,
max(case when x.type='System' then y.response end) as system,
...

from sandbox.tbl_form a
   left outer join sandbox.tbl_formStatus b
   on a.id = b.id
   left outer join sandbox.tbl_formResponse y
   on b.id = y.id
   left outer join sandbox.tbl_formType x
   on y.id = x.typeId
   where b.status = 'Completed' --if you want LEFT JOIN add --or b.status is null
group by a.id
© www.soinside.com 2019 - 2024. All rights reserved.