Hive SQL编码风格:中间表?

时间:2014-01-06 19:35:00

标签: sql hadoop hive

我应该在hive中创建和删除中间表吗?

我可以写类似(简化):

drop table if exists tmp1;
create table tmp1 as
select a, b, c
from input1
where a > 1 and b < 3;

drop table if exists tmp2;
create table tmp2 as
select x, y, z
from input2
where x < 6;

drop table if exists output;
create table output as
select x, a, count(*) as count
from tmp1 join tmp2 on tmp1.c = tmp2.z
group by tmp1.b;
drop table tmp1;
drop table tmp2;

或者我可以把所有内容都卷成一个声明:

drop table if exists output;
create table output as
select x, a, count(*) as count
from (select a, b, c
    from input1
    where a > 1 and b < 3) t1
join (select x, y, z
    from input2
    where x < 6) t2
on t1.c = t2.z
group by t1.b;

显然,如果我不止一次地重用中间表,那么创建它们就非常有意义了。 但是,当他们只使用一次时,我可以选择。

我尝试了两者,第二个是 6% 更快,按墙上时间衡量,但 4% 更慢< / em>由MapReduce Total cumulative CPU time日志输出测量。 这种差异可能在随机误差范围内(由其他过程和c引起)。 但是,组合查询是否有可能导致显着的加速?

另一个问题是:是中间表,只使用一次,在hive代码中是否正常发生,或者应该尽可能避免使用?

4 个答案:

答案 0 :(得分:3)

有一个显着的区别 运行一个大查询将允许优化器在优化中更自由 在这种情况下,最重要的优化之一是hive.exec.parallel中设置的并列。当设置为true时,hive将并行执行独立的阶段 在您的情况下,在第二个查询中想象t1,t2执行更复杂的工作,如group by。在第二个查询t1中,t2将执行simultaniusly,而在第一个脚本中将是串行的。

答案 1 :(得分:3)

我喜欢创建多个视图,然后只在最后创建一个表。这允许Hive优化器减少map-reduce步骤的数量,并且像dimamah和Nigel指出的那样并行执行,但有助于保持非常复杂的管道的可读性。

对于您的示例,您可以将其替换为

CREATE VIEW IF NOT EXISTS tmp1_view
AS
SELECT a, b, c FROM inputs
where a > 1 and b < 3;


create view if not exists tmp2_view as
select x, y, z_
from input2
where x < 6;

drop table if exists output;
create table output as
select x, a, count(*) as count
from tmp1_view join tmp2_view on tmp1_view.c = tmp2_view.z
group by tmp1_view.b;

答案 2 :(得分:1)

我认为合并查询是件好事。它允许Hive查询优化器优化查询。

考虑这个愚蠢的问题:

SELECT COUNT(*) FROM (SELECT * FROM clicks WHERE dt = '2014-01-07') t;

当你运行它时,Hive将只启动一个MapReduce作业。

使用中间表

CREATE TABLE tmp AS SELECT * FROM clicks WHERE dt = '2014-01-07';
SELECT COUNT(*) FROM tmp;

显然会运行两个MapReduce作业。

所以回答你的问题:是的,组合查询可能会导致加速。

答案 3 :(得分:0)

正如您所发现的,时间可能没有太大差异。您很可能希望维护(a)“保存点”/中间回滚或(b)故障排除目的的临时表。否则,管理工作可能不值得记住(或自动化)中间表的清理/删除。