Hive:在主 table 上进行增量更新的最佳方式

Hive: Best way to do incremetal updates on a main table

所以我在 Hive 中有一个 main table,它将存储我所有的数据。

我希望能够加载大约每个月的增量数据更新 有大量数据,数十亿行。会有新的数据 以及更新的条目。

解决此问题的最佳方法是什么,我知道 Hive 最近升级并支持 update/insert/delete。

我一直在想的是以某种方式找到将要更新的条目并将它们从主 table 中删除,然后插入新的增量更新。但是在尝试之后,插入非常快,但是删除非常慢。

另一种方法是使用更新语句来匹配主 table 和增量更新中的键值并更新它们的字段。我还没有尝试过这个。这听起来也非常慢,因为 Hive 必须逐个更新每个条目。

有人知道如何最有效地做到这一点吗?? 一般来说,我对 Hive 和数据库还很陌生。

如果 merge in ACID mode 不适用,则可以使用 FULL OUTER JOIN 或使用 UNION ALL + row_number 进行更新。 要查找将要更新的所有条目,您可以将增量数据与旧数据连接起来:

insert overwrite target_data [partition() if applicable]
SELECT
  --select new if exists, old if not exists
  case when i.PK is not null then i.PK   else t.PK   end as PK,
  case when i.PK is not null then i.COL1 else t.COL1 end as COL1,
  ... 
  case when i.PK is not null then i.COL_n else t.COL_n end as COL_n
  FROM 
      target_data t --restrict partitions if applicable
      FULL JOIN increment_data i on (t.PK=i.PK); 

可以通过限制 target_data 中的分区来优化这一点,这些分区将被覆盖并使用 WHERE partition_col in (select distinct partition_col from increment_data) 连接,或者如果可能的话将分区列表作为参数传递并在 where 子句中使用,它将起作用更快。

此外,如果您想用新数据更新所有列,您可以将此解决方案与UNION ALL+row_number()一起应用,它比完全连接更快:

这是我的 solution/work 如果您使用的是旧的配置单元版本。当目标 table 中有大量数据时,这种方法效果更好,我们不能每次都删除并使用完整数据重新创建。

再创建一个 table 说 delete_keys table。这将保存主 table 中的所有密钥,这些密钥与其代理密钥一起被删除。

在将增量数据加载到 main table 时,与 main table 进行左连接。对于所有匹配的记录,理想情况下我们应该更新主 table。但是相反,我们从主 table 获取所有匹配记录的键(连同代理键)并将其插入到 delete_keys table。现在我们可以将所有增量记录插入到 main table 中,而不管它们是要更新还是插入。

使用 delete-keys table 在主 table 上创建视图,这样就不会获取与 delete-keys table 匹配的键。因此,此视图将成为最终目标 table。此视图将不会显示主 table 中已更新最新记录的记录。