javaanddonet 发表于 2018-4-25 13:17 你的理解对的比如 [mw_shl_code=bash,true]select t1.*,t2.*,t3.* from user_logon_history t1 left join user_logon_history t2 on t1.user_id = t2.user_id and t1.logon_date = t2.logon_date + 1 left join user_logon_history t3 on t2.user_id = t3.user_id and t2.logon_date = t3.logon_date + 1 order by t1.user_id, t1.logon_date;[/mw_shl_code] 其中user_id 就是关联键 重复少比如user_id在小表中都是user_id=1,那么就不要用这个小表了。但是一般来讲,还是小表在前面。 |
desehawk 发表于 2018-4-24 16:14 对对对,你说的很对:把重复关联键少的表放在join前面,做关联可以提高join的效率。 网上很多都是是小表放在前面。这种说法不正确。 不过,这句话也有点不好理解。重复关联键 少的表,怎么理解? 首先说:关联健是什么?应该是指的表中用于和另外一张表进行连接查询的字段吧?这个可以是一个列,也可以是多个列吧? 再说:重复?这个怎么理解?是指需要关联列中的值,有重复的吗? 重复关联健:可以理解为表中的需要和另外一张表进行关联的字段的值,不要重复,如果有重复的值在这个列上,尽量少出现重复的数据。对于这样的表,应该放在join的前面? 不知道这么理解对不对。 |
从这个实现可以看出,我们在写HiveJoin的时候,应该尽可能把小表(分布均匀的表)写在左边,大表(或倾斜表)写在右边。这样可以有效利用内存和硬盘的关系,增强Hive的处理能力。--疑问:上面两个表,那个表小呀?一个pv是3天记录,一个是user2条记录,我怎么觉得是use表是小表而pv表是大表呢?还有从数据分布均匀的程度来看?我感觉pv没有user表分布的均匀呀?起码user表没有重复的数据。 答:对于这个,由于给出的只是示例数据,我们没法判断那个是小表,那个是大表。其实对于优化hive,将小表放在左边,大表放到join的右边。这样可以提高性能。更准确的说法:把重复关联键少的表放在join前面,做关联可以提高join的效率。 |
这时候,Reduce把pv表的数据读入到内存里,然后逐条与硬盘上user表的数据做Join就可以了。--疑问:Reduce为什么会把pv表读入到内存,而不会把user表读入内存?哪里可以看出user表是在硬盘上了? 我们来看: [mw_shl_code=sql,true]INSERTINTO TABLE pv_users SELECT pv.pageid, u.age FROM page_view pv JOIN user u ON (pv.userid = u.userid);[/mw_shl_code] 上面pv表在JOIN 的左边。hive内存加载有一个原则: hive会将join前面的表数据装载内存,位于join前面的表也就是PV表。 至于user本身其实就在硬盘上。这个其实是一个过程。在reduce时候,我们可能会看到内存的使用会增大,所以这时候我们可以推测到,这时候肯定是读取表到内存了。我们能否看到那,这个恐怕需要一定的技术才能不获取到。 |
在每一个Reduce分组中,Key为111的在一起,也就是一台机器上。同时,pv表的数据在这台机器的上端,user表的数据在这台机器的下端。--疑问:这里怎么理解这句话?pv表在这台机器的上端?user表在下端?什么意思? 回答:感觉这个应该是说一左一右,左为上,右有下。其实应该是按照图示所说。一上一下。 |