在准备执行计划pig 0.11时,大量嵌套的bin cond操作符花费了太多时间

zf9nrax1  于 2021-06-21  发布在  Pig
关注(0)|答案(3)|浏览(287)

我需要使用提供的月份生成月份的最后一天。文件中的每一行都包含int格式的month。下面是我想在pig上执行的代码。它在pig0.8(cdh3)上运行得很好,但是当我尝试在pig0.11(cdh4)上执行同样的操作时,它花费了太多的时间(在我有6个节点的集群上大约4分钟)。

A = LOAD '/user/recengd/hitesp/pig/prb' USING PigStorage(',') AS (month:int);
    B = FOREACH A GENERATE  (month== 1 ? 31:
     (month== 2 ? 28:
     (month== 3 ? 31:
     (month== 4 ? 30:
     (month== 5 ? 31:
     (month== 6 ? 30:
     (month== 7 ? 31:
     (month== 8 ? 31:
     (month== 9 ? 30:
     (month== 10 ? 31:
     (month== 11 ? 30:31))))))))))) ;

     Data
     1
     2
     9
     7

当我执行第二行有9个月的条件(即9个内部条件),它工作良好。但是一旦嵌套条件超过这个数字,它就会开始减慢进程。我也在咕噜上试过,也有同样的问题。我不确定这是一些设置问题还是最新版本确实存在问题。

koaltpgm

koaltpgm1#

更清洁的解决方案:
生成包含两列的文本文件:

1,31
2,28
3,31
4,30
5,31
6,30
7,31
8,31
9,30
10,31
11,30
12,31

按如下方式加载文件:

month_day = load '/month_day.txt' using PigStorage(',') as (month:int, day:int);

然后将别名加入到:

C = join A by (month), month_day by (month);

瞧!你有更干净的解决方案。

wecizke3

wecizke32#

我以前从未遇到过使用嵌套binconds的问题,但我想可能我从来没有超过9个条件。也就是说,如果它在较少的条件下工作良好,那么在这种情况下有一种简单的方法来处理它:

B = FOREACH A GENERATE
    (month == 2 ? 28 :
    (month == 4 OR month == 6 OR month == 9 OR month == 11 ? 30 : 31));

请注意,您的方法不处理闰年。
如果你想用一种更简洁的方式来表达第二个条件,这样你就不必输入所有这些条件 OR s、 您可以这样做来稍微缩短它:

((month-4)*(month-6)*(month-9)*(month-11) == 0 ? 30 : 31));

或者用这个技巧来缩短它:

A = LOAD '/user/recengd/hitesp/pig/prb' USING PigStorage(',') AS (month:chararray);
B = FOREACH A GENERATE
    (month == '2' ? 28 :
    (month MATCHES '(4|6|9|11)' ? 30 : 31));
xxe27gdn

xxe27gdn3#

使用大小写表达式!在Pig0.12中是新的:

B = FOREACH A GENERATE (
    CASE month
        WHEN 1 then 31
        WHEN 2 then 30
        ...
    END 
);

参考文献:
https://issues.apache.org/jira/browse/pig-3268
http://pig.apache.org/docs/r0.12.0/basic.html#arithmetic

相关问题