2017-10-05 56 views
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; 

回答

1

查询中有问题。

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

2)BTW where b.status = 'Completed'子句将表b的LEFT连接转换为内部连接,尽管仍然没有ON子句,它将b中的所有记录与a中的所有记录相乘。 3)很可能你根本不需要CTE。只需与ON条款正确连接并使用case when type='User' then response end +使用min()max()的聚合使用id