2016-08-02 46 views
6

我在Hive中有一個非常大的表,我們需要從中加載分區的子集。它看起來是這樣的:使用謂詞下推動態加載Hive中的分區

CREATE EXTERNAL TABLE table1 (
    col1 STRING 
) PARTITIONED BY (p_key STRING); 

我可以加載特定的分區是這樣的:

SELECT * FROM table1 WHERE p_key = 'x'; 

p_key是上table1被分割的關鍵。如果我直接在WHERE子句中對它進行硬編碼,那就很好。但是,我有另一個查詢來計算我需要哪些分區。這是比這更復雜,但讓我們定義它只是爲:

SELECT DISTINCT p_key FROM table2; 

所以現在我應該能夠構建這樣一個骯髒的查詢:

SELECT * FROM table1 
WHERE p_key IN (SELECT DISTINCT p_key FROM table2); 

或寫入內部聯接:

SELECT t1.* FROM table1 t1 
JOIN (SELECT DISTINCT p_key FROM table2) t2 ON t1.p_key = t2.p_key 

但是,當我運行它時,需要足夠的時間讓我相信它正在執行全表掃描。在上述查詢的解釋中,我還可以看到DISTINCT操作的結果在縮減器中使用,而不是在映射器中使用,這意味着映射器不可能知道哪些分區應該加載或不加載。當然,我並不完全熟悉Hive解釋輸出,所以我可能會忽略一些東西。

我在Hive wiki上找到了此頁面:MapJoin and Partition Pruning,相應的ticket表示它是在0.11.0版本中發佈的。所以我應該有它。

可以做到這一點嗎?如果是這樣,怎麼樣?

+0

它高度依賴於您的數據格式。你在列上創建了索引嗎? –

+0

@ThomasJungblut我沒有列上的索引,不,但它是一個分區列。 – KennethJ

回答

0

我不知道如何幫助MapJoin,但在最壞的情況下,你可以動態地創建第二個查詢的東西,如:

SELECT concat('SELECT * FROM table1 WHERE p_key IN (', 
       concat_ws(',',collect_set(p_key)), 
       ')') 
    FROM table2; 

然後執行得到的結果。有了這個,查詢處理器應該能夠修剪不需要的分區。