在准备执行计划PIG 0.11时,重度嵌套的bin cond运算符需要花费太多时间

时间:2013-12-23 10:12:40

标签: apache-pig

我需要使用提供的月份生成该月的最后一天。文件中的每一行都包含以int形式的Month。如果我想在PIG上执行代码。它在PIG 0.8(CDH 3)上工作正常,但是当我尝试在PIG 0.11(CDH 4)上执行相同操作时,它需要花费太多时间(在我的群集上有大约4分钟有6个节点)。

    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 cond)时,它可以正常工作。但是一旦嵌套条件超出该数量,它就会开始减慢这个过程。我也尝试了grunt并遇到同样的问题。我不确定是否存在一些设置问题,或者最新版本确实存在问题。

3 个答案:

答案 0 :(得分:2)

使用CASE表达式!猪0.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

答案 1 :(得分:1)

更清洁的解决方案:

生成一个包含两列的文本文件:

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);

然后将别名加入A:

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

瞧!你有一个更清洁的解决方案。

答案 2 :(得分:0)

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

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

请注意,您的方法无法处理闰年。

如果你想要一种更紧凑的方式来表达第二个条件,这样你就不必输入所有OR个,你可以这样做来略微缩短它:

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

或使用此hack来真正缩短它:

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));