Combiner
1何时使用combiner参数
combiner通常用在非嵌套 的foreach语句中,且此foreach语句中的所有投影运算(projections)都是group(pig的bag被执行group语句之后,默认会有一个group字段)字段中的列表达式或者代数UDF上的表达式。实例如下:
A = load 'studenttab10k' as (name, age, gpa); B = group A by age; C = foreach B generate ABS(SUM(A.gpa)), COUNT(org.apache.pig.builtin.Distinct(A.name)), (MIN(A.gpa) + MAX(A.gpa))/2, group.age; explain C;上面的语句中
(1)group声明可以作为一个整体来引用或者一个单独的字段引用。
(2)group声明和它其中的元素可以在任何投影运算中出现。
上面语句中,多种表达式都可以应用到代数函数中。包括:
(1)列转换函数如ABS可以应用到如SUM这样的代数运算函数中。
(2)代数运算函数(COUNT)同样也可以应用到代数运算函数(DISTINCT)中,但是仅仅是内部的函数是由combiner计算得到的。
(3)数学表达式可以应用到一个或多个代数函数中。
可以通过运行EXPLAIN函数(上面代码最后一句)来检查你的查询是否使用了combiner。
combiner同样可以使用在嵌套语句中,当且仅当该嵌套语句中只有DISTINCT操作。如下:
A = load 'studenttab10k' as (name, age, gpa); B = group A by age; C = foreach B { D = distinct (A.name); generate group, COUNT(D);}最后,combiner的使用是受GROUP和FOREACH声明的周围语法环境影响的 。
2 何时不使用combiner
当操作符处于GROUP和FOREACH语句声明之间时不使用combiner。甚至即使它们仅仅在脚本中相邻的位置,优化器会重新安排它们。下面的实例中,优化器会将FILTER操作移动到FOREACH语句之上,以阻止它使用combiner。
A = load 'studenttab10k' as (name, age, gpa); B = group A by age; C = foreach B generate group, COUNT (A); D = filter C by group.age <30;
注意:上面的规则有一个关于LIMIT的特例,自pig 0.9版本之后,即便是LIMIT处于GROUP和FOREACH之间,还是会使用combiner的。下面的代码总优化器会将LIMIT调整到FOREACH之前,但这并不会阻止combiner的使用。
A = load 'studenttab10k' as (name, age, gpa); B = group A by age; C = foreach B generate group, COUNT (A); D = limit C 20;当多个 FOREACH关联同一个 GROUP时, combiner也 不会被使用。
A = load 'studenttab10k' as (name, age, gpa); B = group A by age; C = foreach B generate group, COUNT (A); D = foreach B generate group, MIN (A.gpa). MAX(A.gpa); .....