在使用Impala进行SQL查询的时候,我们经常会使用join来关联多个表进行查询,获取想要的结果。对于表的数量达到千万甚至上亿的时候,不同的join方式所造成的执行速度,可能差距非常大。Impala提供了两种Join算法-shuffle和broadcast。
适合大表与小表的join,将大表划分成多块,小表广播与这些块进行hash join。
适合大表与大表的join,将两个大表都划分成多块,然后分别进行hash join,有点类似于mapreduce中的shuffle。
已知:ods_xxxxxxx 大表(一天几个亿),即a1表数据量大;dim_t_config 小表(几百条)即a2表数据量少。
预期:对a2进行broadcast ,防止对a1进行broadcast
代码:
SELECT concat('20201111',a2.colv3) ds
,col1
,col2
,sum(col3) col3
,col4
FROM (
SELECT substr(col_update_time, 12, 8) col_update_time
,TYPE
,col1
,(
unix_timestamp(col_update_time)-unix_timestamp(lag((col1_update_time), 1) OVER(PARTITION BY col1 ORDER BY col_update_time ASC))
)/60 col3
,CASE WHEN col10 = 0 THEN 'kudu'
WHEN col10 = 1 THEN 'hive'
WHEN col10 = 2 THEN 'impala'
WHEN col10 = 3 THEN 'spark'
END col3
,col4
FROM ods_xxxxxxx
WHERE ds = '20201111'
) a1
JOIN (
SELECT TYPE
,colv1
,colv2
,colv3
FROM dim_t_config
WHERE ds = '20201112'
) a2
ON a1.col_update_time >= a2.colv1
AND a1.col_update_time <= a2.colv2
AND a1.TYPE = a2.TYPE
GROUP BY a2.colv3
,col1
,col2
,col4;
实际运行时间:122秒
如下图所示:
实际运行执行计划如下: 对 a1表 进行了broadcast
如何使用Hint进行join控制?
代码:添加了如下所示两点 (STRAIGHT_JOIN)和([broadcast])
SELECT STRAIGHT_JOIN concat('20201111',a2.colv3) ds
,col1
,col2
,sum(col3) col3
,col4
FROM (
SELECT substr(col_update_time, 12, 8) col_update_time
,TYPE
,col1
,(
unix_timestamp(col_update_time)-unix_timestamp(lag((col1_update_time), 1) OVER(PARTITION BY col1 ORDER BY col_update_time ASC))
)/60 col3
,CASE WHEN col10 = 0 THEN 'kudu'
WHEN col10 = 1 THEN 'hive'
WHEN col10 = 2 THEN 'impala'
WHEN col10 = 3 THEN 'spark'
END col3
,col4
FROM ods_xxxxxxx
WHERE ds = '20201111'
) a1
JOIN [broadcast] (
SELECT TYPE
,colv1
,colv2
,colv3
FROM dim_t_config
WHERE ds = '20201112'
) a2
ON a1.col_update_time >= a2.colv1
AND a1.col_update_time <= a2.colv2
AND a1.TYPE = a2.TYPE
GROUP BY a2.colv3
,col1
,col2
,col4;
实际运行时间:24.9秒
执行计划:对小表a2进行了broadcast,大表a1避免了broadcast
通过以上测试,看出,选择合适的join方式,性能提升了5倍,平时工作中需要多看执行计划。