mai*_*aia 15 optimization hive buckets join
我正在加入Hive中的两个大表(一个超过10亿行,一个大约是1亿行),如下所示:
create table joinedTable as select t1.id, ... from t1 join t2 ON (t1.id = t2.id);
Run Code Online (Sandbox Code Playgroud)
我以相同的方式对这两个表进行了冲突,将每个表聚为100个桶,但查询仍然需要很长时间.
关于如何提高速度的任何建议?
dim*_*mah 16
正如我所看到的,答案比@Adrian Lange提供的要复杂得多.
首先,您必须了解BucketJoin和Sort-Merge Bucket Join(SMBJ)之间的一个非常重要的区别:
要执行bucketjoin "一个表中的桶数量必须是另一个表中桶的数量的倍数",如前所述,此外hive.optimize.bucketmapjoin必须设置为true.
发出一个连接,如果上述条件发生,配置单元会将其转换为bucketjoin 但是请注意,配置单元不会强制执行bucketing!这意味着创建表格不足以使表格实际被划分到指定数量的桶中,因为除非hive.enforce.bucketing设置为true,否则hive不会强制执行此操作(这意味着实际上由数量设置的桶数量在查询的最后阶段将数据插入表中的reducers).
从性能方面来看,请注意当使用bucketjoin时,单个任务在映射器访问它并执行连接之前将"较小"表读入分布式缓存 - 当您的表具有此阶段时,此阶段可能会非常长且无效~100米行!
在病房之后,联接将与在reducer中完成的常规联接相同.
要执行SMBJ,除了设置hive.optimize.bucketmapjoin.sortedmerge为true 之外,两个表必须在相同列上具有完全相同数量的桶,并按这些列排序.
与之前的优化一样,Hive不会强制执行分段和排序,而是假设您确保表格实际上是分段和排序的(不仅仅是按定义,而是通过hive.enforce.sorting在插入数据时设置或手动排序数据) - 这是非常重要,因为它可能导致两种情况下的错误结果.
从性能方面来看,由于以下原因,此优化更有效:
请注意以下注意事项:
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;/*+ MAPJOIN(b) */都应该在查询中应用a (在较小的表之后select和之后b)另外,不要忘记仅仅这些优化并不总能保证更快的查询时间.
假设您选择执行SMBJ,这会增加在运行联接之前对2个表进行排序的成本 - 因此运行查询的次数越多,您为此排序阶段"支付"的次数就越少.
有时,简单的连接将带来最佳性能,并且上述优化都不会有所帮助,您必须在应用程序/逻辑级别或通过调整MapReduce/Hive设置(如内存使用/并行性等)来优化常规连接过程.
Adr*_*nge 15
当您通过连接键敲击数据时,可以使用Bucket Map Join.为此,一个表中的桶数量必须是另一个表中桶数量的倍数.它可以通过set hive.optimize.bucketmapjoin=true;在查询之前执行来激活.如果表格不符合条件,Hive将只执行正常的内部连接.
如果两个表具有相同数量的存储桶并且数据按存储桶键排序,则Hive可以执行更快的排序合并连接.要激活它,您必须执行以下命令:
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
set hive.optimize.bucketmapjoin=true;
set hive.optimize.bucketmapjoin.sortedmerge=true;
Run Code Online (Sandbox Code Playgroud)
您可以在https://cwiki.apache.org/confluence/download/attachments/27362054/Hive+Summit+2011-join.pdf下找到不同连接技术的一些可视化.