使用谓词下推动态加载Hive中的分区

时间:2016-08-02 12:17:10

标签: hadoop hive

我在Hive中有一个非常大的表,我们需要从中加载一个分区子集。它看起来像这样:

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

我可以像这样加载特定的分区:

SELECT * FROM table1 WHERE p_key = 'x';

p_keytable1分区的关键。如果我直接在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版本中发布的。所以我应该拥有它。

有可能这样做吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:0)

我不确定如何帮助MapJoin,但在最糟糕的情况下,您可以使用以下内容动态创建第二个查询:

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

然后执行获得的结果。有了这个,查询处理器应该能够修剪不需要的分区。