我有一个蜂巢查询其选择约30列,约40万条记录,并将其插入到另一个表。 我有我的SQL子句,它仅仅是一个内连接一个连接。
该查询失败,因为突破了一个Java GC开销限制。
什么奇怪的是,如果我删除的连接语句,并从表(略放量),那么查询工作正常只需要选择数据。
我很新的蜂巢。 我不明白为什么这个连接是导致内存异常。
有什么,我应该知道的有关于我怎么写蜂巢查询,以便它们不会引起这些问题? 任何人都可以解释为什么加入可能会导致这样的问题,而是选择更高的数据量和相同的列数没有。
非常感谢您对这个想法。 谢谢
根据蜂巢和配置的版本,在回答你的问题可能会有所不同。 它会更容易,如果你能随着两个表的创建语句及其大小的估计分享您的确切查询。
为了更好地理解这一问题,让我们通过如何“常规”内的蜂巢加入作品。
蜂巢加入的MapReduce:
下面是在蜂巢内如何加入一个简化的描述被编译到MapReduce的。 在一般情况下,如果你有两个表T1和T2具有连接查询,如:
SELECT
t1.key, t1.value, t2.value
FROM
t1
JOIN
t2 (ON t1.key = t2.key);
其中,T1具有以下内容:
k_1 v1_1
k_2 v1_2
k_3 v1_3
其中,T2具有以下内容:
k_2 v2_2
k_3 v2_3
k_4 v2_4
我们希望连接结果是
k_2 v1_2 v2_2
k_3 v1_3 v2_3
假设表存储在HDFS,其内容将分成文件拆分。 映射器将采取文件分割作为输入,并且发射出密钥表的键列并将该值作为表的值列和标记的复合物(表示该记录是从即T1或T2的表) 。
对于T1:
k_1, <v1_1, t1>
k_2, <v1_2, t1>
k_3, <v1_3, t1>
对于T2:
k_2, <v2_2, t2>
k_3, <v2_3, t2>
k_4, <v2_4, t2>
现在,这些发射出的记录经过洗牌阶段,所有使用相同的按键记录被组合在一起,并送往减速。 每个上下文减少操作是一个键和含有对应于该密钥的所有值的列表。 在实践中,一个减速将执行多项减少操作。
在上面的例子中,我们可以得到以下分组:
k_1, <<v1_1, t1>>
k_2, <<v1_2, t1>, <v2_2, t2>>
k_3, <<v1_3, t1>, <v2_3, t2>>
k_4, <<v2_4, t2>>
下面是在减速会发生什么。 对于每一个在值的列表中的值,如果这些值对应于不同表中的减速器将执行乘法。
对于K_1,没有从T2并没有什么价值被发射。
对于K_2,值的乘法被发射 - K_2,V1_2,v2_2(因为从每个表中的一个值,1×1 = 1)
对于K_3,值的乘法被发射 - K_3,V1_3,v2_3(因为从每个表中的一个值,1×1 = 1)
对于K_4,没有从T1并没有什么价值被发射。 因此,你获得你所期望的结果,你的内连接。
好了,我该怎么办?
这有可能是存在于你的数据扭曲。 换句话说,在减速机获取数据,对应于一些关键值的列表很长,这会导致错误。 为了缓解这一问题,您可以尝试的可用内存碰撞到你的JVM。 您可以通过设置这样做mapred.child.java.opts
到的值等-Xmx512M
在蜂房的site.xml。 您可以通过查询此参数的当前值set mapred.child.java.opts;
在蜂巢外壳。
您可以尝试使用替代“正规军”的加入,如地图加入。 加入的上述解释适用于经常在加入还原剂的加入发生在哪里。 根据蜂巢的版本使用的是,蜂巢可以自动能够转换常规连接映射加入哪个更快(因为加入地图阶段会发生)。 要启用优化,设置hive.auto.convert.join
至true
。 此属性,而推出蜂巢0.7
除了设置hive.auto.convert.join
至true
,你也可以设置hive.optimize.skewjoin
至true
。 这将解决在1描述你的数据的问题倾斜。
非常感谢您的答复马克。 非常感激。
几个小时后,我终于发现,表中的联接语句的顺序有差别。 为了获得最佳的性能和内存管理的最后一个加入应该是最大的表。
改变我的表的顺序在连接声明固定的问题。
见最大的表最后在http://hive.apache.org/docs/r0.9.0/language_manual/joins.html
以上你的解释是非常有用的。 非常感谢