我在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操作的结果在reducer中使用,而不是mapper,这意味着mapper不可能知道应该加载哪些分区。当然,我并不完全熟悉Hive解释输出,所以我可能会忽略一些东西。
我在Hive维基上找到了这个页面:MapJoin and Partition Pruning,而且相应的ticket表示它是在0.11.0版本中发布的。所以我应该拥有它。
有可能这样做吗?如果是这样,怎么样?
答案 0 :(得分:0)
我不确定如何帮助MapJoin,但在最糟糕的情况下,您可以使用以下内容动态创建第二个查询:
SELECT concat('SELECT * FROM table1 WHERE p_key IN (',
concat_ws(',',collect_set(p_key)),
')')
FROM table2;
然后执行获得的结果。有了这个,查询处理器应该能够修剪不需要的分区。