我有一个视图表连接临时表,故意启用了以下参数。
hive.auto.convert.join=true;
hive.execution.engine=tez;
代码段是,
CREATE TABLE STG_CONVERSION AS
SELECT CONV.CONVERSION_ID,
CONV.USER_ID,
TP.TIME,
CONV.TIME AS ACTIVITY_TIME,
TP.MULTI_DIM_ID,
CONV.CONV_TYPE_ID,
TP.SV1
FROM VIEWS TP
JOIN SCU_TMP CONV ON TP.USER_ID = CONV.USER_ID
WHERE TP.TIME <= CONV.TIME;
在正常情况下,两个表都可以包含任意数量的记录 但是,在SCU_TMP表中,预计只有10-50条记录具有相同的用户ID。
但在某些情况下,一些用户ID在SCU Temp表中有大约10k-20k的记录,这会产生交叉产品效果。
在这种情况下,只需1个映射器即可完成。
有没有办法优化它并优雅地运行它?
答案 0 :(得分:1)
我能够通过以下查询找到解决方案。
set hive.exec.reducers.bytes.per.reducer=10000
CREATE TABLE STG_CONVERSION AS
SELECT CONV.CONVERSION_ID,
CONV.USER_ID,
TP.TIME,
CONV.TIME AS ACTIVITY_TIME,
TP.MULTI_DIM_ID,
CONV.CONV_TYPE_ID,
TP.SV1
FROM (SELECT TIME,MULTI_DIM_ID,SV1 FROM VIEWS SORT BY TIME) TP
JOIN SCU_TMP CONV ON TP.USER_ID = CONV.USER_ID
WHERE TP.TIME <= CONV.TIME;
问题出现的原因是,当单个用户ID占据表格时,该用户的加入将通过单个映射器进行处理。
对它进行两处修改,
1)用子查询替换表名 - 在连接之前添加了排序过程
2)将hive.exec.reducers.bytes.per.reducer参数减少到10KB。
在步骤(1)中按时间排序添加了一个shuffle阶段,该阶段均匀分布了之前被用户ID倾斜的数据。
减少每个reducer参数的字节数导致数据分配给所有可用的reducer。
通过这两项改进,10-12小时的跑步减少到45分钟。