Hive中小表与大表关联(join)的性能分析_第1页
Hive中小表与大表关联(join)的性能分析_第2页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、经常看到一些Hive优化的建议中说当小表与大表做关联时,把小表写在前面,这样可以使Hive的关联速度更快,提到的原因都是说因为小表可以先放到内存中,然后大表的每条记录再去内存中检测,最终完成关联查询。这样的原因看似合理,但是仔细推敲,又站不住脚跟。多小的表算小表?如果所谓的小表在内存中放不下怎么办?我用2个只有几条记录的表做关联查询,这应该算是小表了,在查看reduce的执行日志时依然是有写磁盘的操作的。实际上reduce在接收全部map的输出后一定会有一个排序所有键值对并合并写入磁盘文件的操作。写入磁盘(spill)有可能是多次的,因此有可能会生成多个临时文件,但是最终都要合并成一个文件,即

2、最终每一个reduce都只处理一个文件。我做了一个实验,用1条记录的表和3亿多条记录的表做join,无论小表是放在join的前面还是join的后面,执行的时间几乎都是相同的。再去看reduce的执行日志仕条记录的表在join前或者join后两次查询的reduce日志几乎也是一摸一样的。如果按照上面的说法把join左侧的表放内存等待join右侧的表到内存中去检测,那么当3亿多条记录的表放在join左侧时,内存肯定是无法容下这么多记录的,势必要进行写磁盘的操作,那它的执行时间应该会比小表在join前时长很多才对,但事实并不是这样,也就说明了上面说到的原因并不合理。事实上“把小表放在前面做关联可以提

3、高效率”这种说法是错误的。正确的说法应该是“把重复关联键少的表放在join前面做关联可以提高join的效率。”分析一下Hive对于两表关联在底层是如何实现的。因为不论多复杂的Hive查询,最终都要转化成mapreduce的JOB去执行,因此Hive对于关联的实现应该和mapreduce对于关联的实现类似。而mapreduce对于关联的实现,简单来说,是把关联键和标记是在join左边还是右边的标识位作为组合键(key),把一条记录以及标记是在join左边还是右边的标识位组合起来作为值(value)。在reduce的shuffle阶段,按照组合键的关联键进行主排序,当关联键相同时,再按照标识位进行

4、辅助排序。而在分区段时,只用关联键中的关联键进行分区段/这样关联键相同的记录就会放在同一个valuelist中,同时保证了join左边的表的记录在valuelist的前面,而join右边的表的记录在valuelist的后面。例如AjoinBON(A.id=b.id),假设A表和B表都有1条id=3的记录,那么A表这条记录的组合键是(3,0),B表这条记录的组合键是(3,1)。排序时可以保证A表的记录在B表的记录的前面。而在reduce做处理时,把id=3的放在同一个valuelist中,形成key=3,valuelist=A表id=3的记录,B表id=3的记录接下来我们再来看当两个表做关联时r

5、educe做了什么。Reduce会一起处理id相同的所有记录。我们把valuelist用数组来表示。1) Reduce先读取第一条记录v0,如果发现v0是B表的记录,那说明没有A表的记录,最终不会关联输出,因此不用再继续处理这个id了,读取v0用了1次读取操作。2) 如果发现v0到vlength-1全部是A表的记录,那说明没有B表的记录,同样最终不会关联输出,但是这里注意,已经对value做了length次的读取操作。3) 例如A表id=3有1条记录,B表id=3有10条记录。首先读取v0发现是A表的记录,用了1次读取操作。然后再读取v1发现是B表的操作,这时v0和v1可以直接关联输出了,累计

6、用了2次操作。这时候reduce已经知道从v1开始后面都是B表的记录了,因此可以直接用v0依次和v2,v3v10做关联操作并输出,累计用了11次操作。4) 换过来,假设A表id=3有10条记录,B表id=3有1条记录。首先读取v0发现是A表的记录,用了1次读取操作。然后再读取v1发现依然是A表的记录,累计用了2次读取操作。以此类推,读取v9时发现还是A表的记录,累计用了10次读取操作。然后读取最后1条记录v10发现是B表的记录,可以将v0和v10进行关联输出,累计用了11次操作。接下来可以直接把v1v9分别与v10进行关联输出,累计用了20次操作。5) 再复杂一点,假设A表id=3有2条记录,

7、B表id=3有5条记录。首先读取v0发现是A表的记录,用了1次读取操作。然后再读取v1发现依然是A表的记录,累计用了2次读取操作。然后读取v2发现是B表的记录,此时v0和v2可以直接关联输出,累计用了3次操作。接下来v0可以依次和v3v6进行关联输出累计用了7次操作。接下来v1再依次和v2v6进行关联输出,累计用了12次操作。6) 把5的例子调过来,假设A表id=3有5条记录,B表id=3有2条记录。先读取v0发现是A表的记录,用了1次读取操作。然后再读取v1发现依然是A表的记录,累计用了2次读取操作。以此类推,读取到v4发现依然是A表的记录,累计用了5次读取操作。接下来读取v5,发现是B表的记录,此时v0和v5可以直接关联输出,累计用了6次操作。然后v0和v6进行关联输出,累计用了7次操作。然后v1分别与v5、v6关联输出,累计用了9次操作。V2分别与v5、v6关联输出,累计用了11次操作。以此类推,最后v4分别与v5、v6关联输出,累计用了15次操作。7) 额外提一下,当reduce检测A表的记录时,还要记录A表同一个key的记录的条数/当发现同一个key的记录个数超过hive.skewjoin.key的值(默认为1000000)时,会在reduce的日志中打印出该key,并

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论