前言
hive中取多个key时,为什么用了json_tuple,效率反而比get_json_object慢了一些?
文将介绍解析json字符串的两个函数:get_json_object和json_tuple。
测试表
表结构如下:
其中meta 字段数据, 数据表是 test_table
{{"a":1,"b":2},{"a":3,"b":4}}
功能对比
get_json_object方法可以处理的 path更为丰富,能够支持正则、支持嵌套、取多层等。
而json_tuple简单粗暴,只能解析第一层key具体介绍如下:
get_json_object
函数的作用:用来解析json字符串的一个字段:
select get_json_object(meta,'$.a') as filtertype
,get_json_object(meta,'$.b')as filtersubtype
from test_table
运行结果 仅有一条数据,其实应该是2条:
filtertype filtersubtype
1 2
json_tuple
函数的作用:用来解析json字符串中的多个字段
select b.a
,b.b
from test_table a
lateral view json_tuple(meta,'a', 'b', ) b as
a, b;
运行结果:
filtertype filtersubtype
1 2
3 4
具体功能介绍可以参考下文
Hive lateral view ,get_json_object,json_tuple 用法_击水三千里的博客-CSDN博客
效率对比
1、get_json_object缓存jsonObject (并非无脑解析多次)
一般情况下,由json字符串序列化成jsonObject这个过程是最耗费时间的。从代码中可以看到,get_json_object函数会缓存jsonObject,也就是说json字符串转化为jsonObject的过程只有一次。并不是解析多次。
2、执行计划层面(get_json_object更简洁,json_tuple更繁重)
从下图中可以看到,get_json_object的执行计划,只有一个selectOperator ,非常简单
而json_tuple是属于udtf函数,中间会有udtf相关的operator
详情可以参考:你真的了解Lateral View explode吗? 这篇
执行计划图大概是这个样子:
图是从 你真的了解Lateral View explode吗? 中取的,不太合适,但基本流程是一样的
json_tuple在这个过程中也是有一定的性能损耗的
总结:我们们在实际用的时候,不要盲从,用get_json_object也是没关系的,况且正常情况下,一次也不会取成千上万个key值... 重要的是要保证,我们的json字符串一定不要存的太长,太大,这样的话,不管用哪个函数,效率都不会好
使用正则表达式对json 数据进行处理
对于上面的test_table 使用:
select get_json_object(B.stock_code,'$.a') as a,
get_json_object(B.stock_code,'$.b') as b,
from (
select split(regexp_replace(regexp_extract(meta
,'^\[(.+)\]$',1),'\\}\\,\\{', \'\}\\|\\|\\{''),'\\|\|') as stock_codes
from test_table
) A lateral view explode(A.stock_codes) B as stock_code