Hive与子查询的聚合结果进行比较

时间:2017-06-21 11:16:00

标签: sql hadoop hive delta

我有一张表(例如名为来源),如下所示:

-------------
|Name|ID|...|
-------------
|A   |1 |...|
|A   |2 |...|
|A   |3 |...|
|B   |1 |...|
|B   |2 |...|
|C   |1 |...|
-------------

所以每个名称可能有多个条目,每个条目都有一个递增的 ID (由名称进行分区,因为您可能已经获得了它到现在为止。

现在,我有另一个表格(名为 Dest ),我从来源表格加载,例如每日批次。但是,我只想从来源加载增量,因此如果我的 Dest 表格如下:

-------------
|Name|ID|...|
-------------
|A   |1 |...|
|A   |2 |...|
|B   |1 |...|
-------------

我只想将来源的差异复制到目的地,这将是:

-------------
|Name|ID|...|
-------------
|A   |3 |...|
|B   |2 |...|
|C   |1 |...|
-------------

由于其他原因,我无法使用时间戳或减号,因此找到差异的唯一方法是获取每个名称的 MAX(ID) 并仅检索条目>每个名称的MAX(ID)

最快的实施方式是通过子查询为每个名称准备所有 MAX(ID),并使用它来消除较小的 ID S:

SELECT s.* FROM Source s 
LEFT JOIN (
 SELECT d.NAME, MAX(d.ID) AS MAX_ID
 FROM Dest d
 GROUP BY d.NAME) n
ON s.NAME = n.NAME
WHERE s.ID > COALESCE(n.MAX_ID,0)

但是,由于表格中有很多条目,我认为这不会很有效,除非Hive自动优化它,我不确定。

我希望做的是这样的事情:

SELECT s.* FROM Source s 
WHERE s.ID > (SELECT COALESCE(MAX(d.ID),0)
              FROM Dest d
              WHERE d.NAME = s.NAME)

这样我就可以避免为所有条目计算 MAX(ID),并且只计算当前名称的值。但在Hive中显然是不可能的。

所以我的问题是,在Hive中实现这种增量检测的最佳和最佳性能是什么?

1 个答案:

答案 0 :(得分:0)

为什么不使用left joinwhere

SELECT s.*
FROM Source s LEFT JOIN
     Dest d
     ON s.NAME = d.NAME AND s.ID = d.ID
WHERE d.NAME IS NULL;

如果您确实需要使用Dest中的最大ID,那么使用GROUP BY的方法在Hive中应该没问题。