如果是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的輸出都會產生臨時文件”。