在之前的文章 MapReduce Map Side Join - 用户经纬度转换的例子 中, 我们提过如何使用 Hadoop MapReduce 进行 Map Side Join 开发, 但那个需求是一个比较特殊的例子, 大部分情况都没有这么特殊的 join 逻辑, 即直接用 HiveSQL 而不需要进行 MapReduce Job 开发就可以完成.
例子
假设有两张表: 大表 order 和小表 city, 现在需要查询每个订单所属的城市名称, SQL 可能是这样的:
SELECT * FROM orders o JOIN cities c ON (o.city_id = c.id); |
但是, 运行之后你会发现比较缓慢, 即我们之前提到的大小表 Join 的问题, 因为有 reduce 的过程.
SQL 实现 Map Side Join
Hive hint
要实现 Map Side Join 来加快查询, 但又不想写 MapReduce Job 代码, 正好 Hive 中有一个 hint 可以实现我们的需求:
SELECT /*+ MAPJOIN(c) */ * FROM orders o JOIN cities c ON (o.city_id = c.id); |
如上, /*+ MAPJOIN(c) */
这个 hint, 其中的 c
就是我们指定的小表.
设置
除了 hint 之外, Hive 还可以设置 hive.auto.convert.join
为 true
来开启自动转换, 如果 Hive 发现表的大小小于 hive.mapjoin.smalltable.filesize
(默认是 25MB).
不过, Hive 有个限制, 同一查询里相同表名或表别名的不能在其他不同的列再进行 Join , 这个问题只要我们不用相同的表别名就好了.
参考
https://grisha.org/blog/2013/04/19/mapjoin-a-simple-way-to-speed-up-your-hive-queries/