2013-11-25 40 views
11

我在蜂巢连接两个大表(其中一个是超过十亿行,一个是大约100万行),像这样:蜂巢 - 高效连接两个表

create table joinedTable as select t1.id, ... from t1 join t2 ON (t1.id = t2.id); 

我已经时段的两个表同样的方法,通过将每个id聚类为100个桶,但查询仍然需要很长时间。

关于如何加快速度的建议?

回答

13

当您通过连接键对数据进行分段处理时,可以使用Bucket Map Join。为此,一个表中的桶的数量必须是另一个表中的桶的数量的倍数。可以在查询前执行set hive.optimize.bucketmapjoin=true;来激活它。如果表格不符合条件,Hive将简单地执行正常的Inner Join。

如果两个表具有相同数量的存储桶并且数据按存储桶密钥排序,则Hive可以执行更快的排序 - 合并联接。要激活它,你必须执行以下命令:

set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat; 
set hive.optimize.bucketmapjoin=true; 
set hive.optimize.bucketmapjoin.sortedmerge=true; 

你可以找到不同的某些可视https://cwiki.apache.org/confluence/download/attachments/27362054/Hive+Summit+2011-join.pdf下加入技术。

+0

我会给它一个镜头。在Hive中索引是否有帮助?即。如果我通过id为t1和t2编制索引? – maia

+0

我如何估计要使用多少个桶? – maia

+0

索引不会提高联接中的性能。它们用于检索单行,例如在'WHERE id = 123'中。铲斗是这里最好的选择。 –

11

正如我所看到的,答案比@Adrian Lange提供的要复杂一点。

首先,你必须了解BucketJoin和排序合并桶加入(SMBJ)之间一个非常重要的区别:

要执行bucketjoin“水桶在一个表中的金额必须是量的倍数如前所述,另外hive.optimize.bucketmapjoin必须设置为true。
发出加入,配置单元会将其转换为bucketjoin如果发生上述情况但是请注意,配置单元不会强制执行分配!这意味着创建表分区是不够的,因为表实际上被分配到指定数量的桶中,因为除非hive.enforce.bucketing设置为true,否则配置单元不会执行此操作(这意味着实际上桶的数量由在查询的最后阶段将数据插入表中的减速器的数量)。
从性能方面来说,请注意当使用bucketjoin a 单个任务在映射器访问它并进行连接之前将“较小”表读入分布式缓存中 - 此阶段可能会非常长当你的桌子有100米左右时,效果不佳!
之后,加入过程与在减速器中进行的常规加入相同。

要执行SMBJ两个表必须有水桶完全相同的量,在同一列,除了这些列排序,以设置hive.optimize.bucketmapjoin.sortedmerge为true。
与之前的优化一样,Hive并没有强制执行分段和排序,而是假定您确保表格实际是分段和排序的(不仅按照定义,而且通过设置hive.enforce.sorting或在插入时手动排序数据) - 这是非常重要的,因为它可能导致在两种情况下的错误结果
作为从服务表现方面,这种优化的方式更有效,原因如下:

  1. 每个映射器读取两个水桶,有联接正在执行对分布式缓存加载没有单一的任务争
  2. 是合并 - 排序连接,因为数据已经被排序,效率更高。

请注意以下事项:

    在这两种情况下
  • set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
    应执行
  • 在这两种情况下/*+ MAPJOIN(b) */应在查询(可应用select后马上其中b是小表)
  • 有多少个水桶?
    这应该从这个角度来看:考虑应该严格适用于更大的表格,因为它从这个方向有更多的影响,后者的配置将作为必须应用到更小的表格。我认为根据经验,每个桶应该包含1到3个块,可能在2个块附近。所以如果你的块大小是256MB,它对我来说合理的是在大表中的每个桶中有〜512MB的数据,所以这成为一个简单的分割问题。

另外,不要忘记,这些优化本身并不总能保证更快的查询时间。
假设您选择执行SMBJ,这会增加在运行联接之前对2个表进行排序的成本 - 因此您运行查询的次数越少,您将为此排序阶段“付费”的次数越少。

有时候,简单的连接会导致最佳的性能,上述优化都不会起到帮助作用,您将不得不在应用程序/逻辑级别或通过调整MapReduce/Hive设置(如内存使用情况)来优化常规连接过程/并行等

0

我不认为它必须的标准“一个表中的桶的数量必须是另一个表中桶的数量的倍数”,对于地图桶连接,我们可以有相同数量的桶也。