hive中join的on和where

简介:

昨天发现线上有一个job用了1w多个map,导致其他job一直在等待mapred资源


wKioL1L-J1eSz5PlAANGULZV--k268.jpg

为了避免影响别的job,暂时先杀掉,然后分析原因。

一般产生大量map有两个原因:

1.输入的数据量比较大,导致根据split产生map时有大量的map产生

2.小文件比较多,同时没有使用combine的inputformat,这样在产生map时,每个文件就会至少生成一个split。

因为默认使用了combine的inputformat,并设置了合适的合并条件,因此排除第二个原因。

运行的sql:

1
2
3
4
5
6
7
8
9
10
select  aa1.order_id,aa1.user_id,coalesce(b1.total, 0 ) as total,
to_date(aa1.add_time) ord_dt,
b1.update_time,
datediff(to_date(aa1.add_time),to_date(b1.update_time)) mark
FROM
dddd.dd aa1
left outer join
dddd.cc b1
on
(aa1.user_id=b1.user_id and aa1.dt= '20140212'  and b1.dt= '20140211' );


通过explain extended分析sql:

发现aa1表并没有根据aa1.dt='20140212'来过滤partition,而是对表的文件进行了全局的扫描。

如果是inner join的话,可以正常过滤,也就是在left join的情况下,左边的表不会根据on的条件来过滤数据,可以通过在后面再增加where语句来实现过滤的功能。

分析两者的执行计划区别:

1.left join + on

1
(TOK_QUERY (TOK_FROM (TOK_LEFTOUTERJOIN (TOK_TABREF (TOK_TABNAME vipdw dw_trd_order_cut) aa1) (TOK_TABREF (TOK_TABNAME vipdw dw_vip_vmark) b1) (and (and (= (. (TOK_TABLE_OR_COL aa1) user_id) (. (TOK_TABLE_OR_COL b1) user_id)) (= (. (TOK_TABLE_OR_COL aa1) dt)  '20140212' )) (= (. (TOK_TABLE_OR_COL b1) dt)  '20140211' )))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (. (TOK_TABLE_OR_COL aa1) order_id)) (TOK_SELEXPR (. (TOK_TABLE_OR_COL aa1) user_id)) (TOK_SELEXPR (TOK_FUNCTION coalesce (. (TOK_TABLE_OR_COL b1) total)  0 ) total) (TOK_SELEXPR (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL aa1) add_time)) ord_dt) (TOK_SELEXPR (. (TOK_TABLE_OR_COL b1) update_time)) (TOK_SELEXPR (TOK_FUNCTION datediff (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL aa1) add_time)) (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL b1) update_time))) mark))))

2.left join + on + where

1
(TOK_QUERY (TOK_FROM (TOK_LEFTOUTERJOIN (TOK_TABREF (TOK_TABNAME vipdw dw_trd_order_cut) aa1) (TOK_TABREF (TOK_TABNAME vipdw dw_vip_vmark) b1) (and (and (= (. (TOK_TABLE_OR_COL aa1) user_id) (. (TOK_TABLE_OR_COL b1) user_id)) (= (. (TOK_TABLE_OR_COL aa1) dt)  '20140212' )) (= (. (TOK_TABLE_OR_COL b1) dt)  '20140211' )))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (. (TOK_TABLE_OR_COL aa1) order_id)) (TOK_SELEXPR (. (TOK_TABLE_OR_COL aa1) user_id)) (TOK_SELEXPR (TOK_FUNCTION coalesce (. (TOK_TABLE_OR_COL b1) total)  0 ) total) (TOK_SELEXPR (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL aa1) add_time)) ord_dt) (TOK_SELEXPR (. (TOK_TABLE_OR_COL b1) update_time)) (TOK_SELEXPR (TOK_FUNCTION datediff (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL aa1) add_time)) (TOK_FUNCTION to_date (. (TOK_TABLE_OR_COL b1) update_time))) mark)) (TOK_WHERE (= (. (TOK_TABLE_OR_COL aa1) dt)  '20140212' ))))


可以看到在增加where后增加了

(TOK_WHERE (= (. (TOK_TABLE_OR_COL aa1) dt) '20140212')) 的逻辑,优化器会先进行partition purge,然后再进行join操作。


其实在mysql中也是这种情况:

inner join中的join key可以作为过滤条件。
left/right outer join类的join key不能作为驱动表的过滤条件,要实现过滤的话可以通过on + where组合。


本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1359315,如需转载请自行联系原作者
相关文章
|
11月前
|
SQL 缓存 分布式计算
54 Hive的Join操作
54 Hive的Join操作
117 0
|
22天前
|
SQL 分布式计算 JavaScript
Hive的JOIN连接
Hive的JOIN连接
34 5
|
SQL 存储 大数据
大数据Hive Join连接查询
大数据Hive Join连接查询
84 0
|
SQL HIVE
hive:条件查询、join关联查询、分组聚合、子查询
hive:条件查询、join关联查询、分组聚合、子查询
711 0
hive:条件查询、join关联查询、分组聚合、子查询
Hive中的in、exists和left semi join
Hive中的in、exists和left semi join
Hive中的in、exists和left semi join
|
SQL 消息中间件 监控
​实战:Flink 1.12 维表 Join Hive 最新分区功能体验
我们生产常有将实时数据流与 Hive 维表 join 来丰富数据的需求,其中 Hive 表是分区表,业务上需要关联上 Hive 最新分区的数据。上周 Flink 1.12 发布了,刚好支撑了这种业务场景,我也将 1.12 版本部署后做了一个线上需求并上线。对比之前生产环境中实现方案,最新分区直接作为时态表提升了很多开发效率,在这里做一些小的分享。
​实战:Flink 1.12 维表 Join Hive 最新分区功能体验
|
SQL HIVE
hive无法执行带where语句的SQL
应用场景 当在伪分布式集群上,搭建部署了hive以后,发现hive无法执行带where语句的sql,那hive将无法使用,下面介绍解决该问题的方案! 操作步骤 hive连接执行sql,可以执行带wher...
1759 0
下一篇
无影云桌面