如果是2个大表union会写几次临时文件到hdfs目录,数据量如何计算
在Hive on Tez中,两个大表执行UNION
操作时,临时文件的写入次数和数据量,取决于UNION
的类型(UNION ALL
还是UNION
去重)以及执行计划的Stage划分。以下分场景详细说明:
一、临时文件写入次数:与Stage数量直接相关
Tez会将UNION
操作解析为多个Stage(计算阶段),每个Stage的输出都会写入HDFS临时目录(作为下一个Stage的输入)。因此,临时文件的“写入次数”等价于参与计算的Stage数量。
1. 场景1:UNION ALL
(不去重,仅合并)
UNION ALL
仅需将两个表的结果“直接拼接”,执行计划通常包含3个Stage:
- Stage 1:扫描并处理第一个表(如过滤、字段转换等,若无需处理则仅扫描),输出结果写入临时目录;
- Stage 2:扫描并处理第二个表,输出结果写入临时目录;
- Stage 3:合并Stage 1和Stage 2的临时结果(无需去重),输出最终合并结果到临时目录,最后通过原子操作写入目标表。
临时文件写入次数:3次(每个Stage各写1次)。
2. 场景2:UNION
(自动去重,等价于UNION DISTINCT
)
UNION
需要对两个表的合并结果去重,执行计划比UNION ALL
多一个“去重Stage”,共4个Stage:
- Stage 1:处理第一个表,输出临时文件;
- Stage 2:处理第二个表,输出临时文件;
- Stage 3:合并Stage 1和Stage 2的结果(此时数据可能有重复),输出到临时目录;
- Stage 4:对Stage 3的结果执行去重(通常通过
Reduce
阶段的DISTINCT
操作),输出去重后的结果到临时目录,最后写入目标表。
临时文件写入次数:4次(每个Stage各写1次)。
二、临时文件的数据量计算
临时文件的数据量取决于每个Stage的输出数据量,受原始表大小、处理逻辑(如过滤、转换)、数据格式(压缩与否)影响。以下为简化计算(假设无过滤/转换,默认压缩格式如ORC):
1. 场景1:UNION ALL
- Stage 1临时文件:约等于第一个表的实际存储量(记为
A
,如100GB); - Stage 2临时文件:约等于第二个表的实际存储量(记为
B
,如200GB); - Stage 3临时文件:约等于
A + B
(合并后无去重,300GB)。
总临时数据量:A + B + (A + B) = 2*(A + B)
(3次写入的总和)。
2. 场景2:UNION
(去重)
- Stage 1临时文件:
A
; - Stage 2临时文件:
B
; - Stage 3临时文件:
A + B
(合并后未去重); - Stage 4临时文件:约等于
A + B - C
(C
为重复数据量,假设重复50GB,则为250GB)。
总临时数据量:A + B + (A + B) + (A + B - C) = 3*(A + B) - C
(4次写入的总和)。
三、关键影响因素
- 数据压缩:若启用ORC/Parquet等压缩格式,临时文件实际存储量会比原始文本小3-5倍(需按压缩后大小计算);
- 处理逻辑:若
UNION
前有WHERE
过滤或字段裁剪,Stage 1/2的输出量会小于原始表大小; - 分桶/分区:若表是分桶或分区表,且
UNION
仅涉及部分分区,临时文件量会按实际涉及的分区数据计算; - 重复数据比例:
UNION
去重时,重复数据越多(C
越大),Stage 4的输出量越小,总临时数据量越少。
总结
UNION ALL
:3次临时文件写入,总数据量约2*(A + B)
;UNION
(去重):4次临时文件写入,总数据量约3*(A + B) - C
;- 实际数据量需结合压缩、过滤、重复率等因素调整,核心是“每个Stage的输出都会产生临时文件”。