当我有一个在整个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;
您的查询中存在问题。
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