Join 在配置单元中模拟间隔联接
我使用的是蜂巢0.13 我有两张桌子: 数据表。列:id,time。1E10行。 我的地图表。列:id、名称、开始时间、结束时间。1E6行。 对于数据表中的每一行,我希望从匹配id和时间间隔的mymap表中获取名称。所以我想做一个连接,比如:Join 在配置单元中模拟间隔联接,join,hive,Join,Hive,我使用的是蜂巢0.13 我有两张桌子: 数据表。列:id,time。1E10行。 我的地图表。列:id、名称、开始时间、结束时间。1E6行。 对于数据表中的每一行,我希望从匹配id和时间间隔的mymap表中获取名称。所以我想做一个连接,比如: select data.id, time, name from data left outer join mymap on data.id = mymap.id and time>=start_time and time<end_time 众
select data.id, time, name from data left outer join mymap on data.id = mymap.id and time>=start_time and time<end_time
众所周知,对于数据中的每一行,mymap中都有0或1个匹配项
以上查询在配置单元中不受支持,因为它是非相等联接。将不等式条件移动到过滤器不工作的位置会导致连接在应用过滤器之前爆炸:
select data.id, time, name from data left outer join mymap on data.id = mymap.id where mymap.id is null or (time>=start_time and time<end_time)
我知道,由于存在id匹配但没有匹配间隔的情况,查询并不完全等效。正如我在这里所描述的,这可以解决:
我该怎么做呢?您可以执行连接,然后从该表中进行查询。我没有测试这段代码,但它的内容如下
select id
,time
,name
from (
select d.id
,d.time
,m.name
,m.start_time
,m.end_time
from data as d LEFT OUTER JOIN mymap as m
ON d.id = m.id
) x
where time>=start_time
AND time<end_time
您可以通过平展表2中的数据结构并使用UDF来处理连接的记录,从而潜在地绕过这个问题
select
id,
time,
nameFinderUDF(b.name_list, time) as name
from
data a
LEFT OUTER JOIN
(
select
id,
collect_set(array(name,cast(start_time as string),cast(end_time as string))) as name_list
from
mymap
group by
id
) b
ON (a.id=b.id)
使用UDF执行以下操作:
public String evaluate(ArrayList<ArrayList<String>> name_list,Long time) {
for (int i;i<name_list.length;i++) {
if (time >= Long.parseLong(name_list[i][1]) && time <= Long.parseLong(name_list[i][2])) {
return name_list[i][0]
return null;
}
这种方法应该使合并为1:1,但它可能会创建一个相当大的重复多次的数据结构。它仍然比直接连接更有效。这类似于我的第二个查询。问题是我的查询完全不同。您试图在外部联接的where子句中传递条件,我正在执行嵌套查询。你试过这个代码吗?我创建了示例数据,它可以工作。我不确定您为什么认为第二个查询有用。无论如何,问题在于大数据1。一张2×100亿的桌子并没有那么大。2.如果您的数据太大,则查询将不起作用,这就是MapReduce-scale的要点。从你的数据中选取一个子集,然后对照你的数据运行我的数据。我打赌我的更快。我认为这里的问题不是100亿行——而是mymap表中每个id的数据可能非常密集——如果只有1000个id,那么100亿行就变成了10万亿!