【问题标题】:Hive UDF returning an array called twice - performance?Hive UDF 返回一个称为两次的数组 - 性能?
【发布时间】:2015-06-22 13:40:20
【问题描述】:

我在 hive 中创建了一个 GenericUDF,它接受一个字符串参数并返回一个包含两个字符串的数组,类似于:

> select normalise("ABC-123");
...
> [ "abc-123", "abc123" ]

UDF 通过 JNI 调用 C++ 程序,为每一行计算返回数据,因此出于性能原因,最好只对每个输入行调用一次。

但是,我希望能够从数组中获取每个值并将其放入输出表中的单独字段中。我知道我能做到:

> select normalise("ABC-123")[0] as first_string, normalise("ABC-123")[1] as second_string;

hive 将调用 normalize 函数两次 - 每次在此语句中使用一次 - 还是会看到两个调用具有相同的参数并且只调用一次,缓存输出,并使用缓存而不是使第二次打电话?

如果要每行调用两个 UDF,还有哪些其他选项可以使用此 UDF 并将输出数组中的两个字符串放入输出表中的单独列中? (我认为 INLINE 不会在这里工作)

这个函数的用例类似于:

a|b
1|ABC-123
2|DEF-456

select a, normalise(b)[0] as first_string, normalise(b)[1] as second_string;

【问题讨论】:

    标签: hive hiveql


    【解决方案1】:

    如果你想确保 udf 只被调用一次,你可以先将结果保存到一个临时表中:

    create table tmp as 
    select a, normalize(b) arr
    from mytable;
    
    
    select a, arr[0] first_string, arr[1] second_string
    from tmp;
    

    也就是说,如果我是你,我可能不会担心这种性能调整,在我看来,Hive 最好以“蛮力”的心态来处理:只需编写最简单的代码来实现你的任务,如果速度很慢,您可以随时向集群添加更多节点。

    此外,您是否真的需要为您的任务定制 UDF,或者您是否可以通过使用内置 Hive 函数来简化您的代码库,这可能值得考虑;在您给出的示例中:

    select lower(b) as first_string, regexp_replace(lower(b), '-', '') as second_string
    

    【讨论】:

    • 不幸的是,规范化函数比小写和删除连字符要复杂一些 - C++ 代码库由各种系统共享,我们必须使用它。我的同事也告诉我不要担心表现,但我脑子里有一个不会闭嘴的小声音:)
    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    相关资源
    最近更新 更多