Hive解析json字段,虽然json_tuple写法很优雅,但是效率并不一定高哦

    在写Hive SQL时,需要从一个json列中解析出多个key的信息,查阅资料发现到有两种写法,一种是get_json_object,另外一种是json_tuple。两种用法的示例如下所示

 

get_json_object示例:

select
get_json_object(json_str_column,'$.a1') as a1,
get_json_object(json_str_column,'$.a2') as a2,
get_json_object(json_str_column,'$.a3') as a3,
from my_table;

json_tuple示例:

select B.a1, B.a2, B.a3 
from my_table A  
lateral view json_tuple(json_str_column, 'a1', 'a2', 'a3') B as a1, a2, a3;

    从写法上来说,json_tuple的写法SQL语句更少,更加的优雅,尤其当要解析出来的字段非常多时更加明显,但是json_tuple的性能如何呢?

 

再使用explain看下它们的执行计划:

两者的执行计划分别如下图所示:

    get_json_object() 是个UDF,在Mapper阶段的列投影时完成获取解析json的操作,如果要获取多个key,那么json字段就要解析多次!

    

    json_tuple() 这个函数在Hive里面是使用UDTF来实现的,即普通的一行转多行。它会生成两个Select Operator 操作,一个扫描不用解析的数据,生成一行,另外一个扫描需要解析的数据进行解析,然后再使用Lateral View Join Operator 操作将这两部分数据join关联起来。如下图所示:

 

LateralViewJoinOperator:

    但是这里的Join并不是真正会触发Shuffle的join,只是讲非UDTF和UDTF字段通过ArrayList的addAll()连接在一起而已:

// acc is short for accumulator. It's used to build the row before forwarding
ArrayList<Object> acc = new ArrayList<Object>();
// selectObjs hold the row from the select op, until receiving a row from
// the udtf op
ArrayList<Object> selectObjs = new ArrayList<Object>();

/**
 * An important assumption for processOp() is that for a given row from the
 * TS, the LVJ will first get the row from the left select operator, followed
 * by all the corresponding rows from the UDTF operator. And so on.
 */
@Override
public void process(Object row, int tag) throws HiveException {
  StructObjectInspector soi = (StructObjectInspector) inputObjInspectors[tag];
  if (tag == SELECT_TAG) {
    selectObjs.clear();
    selectObjs.addAll(soi.getStructFieldsDataAsList(row));
  } else if (tag == UDTF_TAG) {
    acc.clear();
    // 这里就是所谓的join,只是连接再一起而已
    acc.addAll(selectObjs);
    acc.addAll(soi.getStructFieldsDataAsList(row));
    forward(acc, outputObjInspector);
  } else {
    throw new HiveException("Invalid tag");
  }

}

 

    最后说下个人测试得出来的结论,感觉非常神奇,如果json字段并不是特别多(几十个Key),并且从json字段中解析的key并不是特别多时,json_tuple的性能要远低于get_json_object!

    非常神奇...暂时还是不明白为啥json_tuple会慢,先记录下,后续慢慢分析好了...如果又知道的,麻烦和我说一下,感谢感谢!

 

参考:

    https://www.cnblogs.com/BlueSkyyj/p/9720346.html(get_json_object使用方式)

    https://www.cnblogs.com/zzhangyuhang/p/9791795.html(lateral view介绍)

    https://zhuanlan.zhihu.com/p/137482744(LateralViewJoinOperator解析)

    https://blog.csdn.net/lidongmeng0213/article/details/110877351(LateralViewJoinOperator解析)

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值