用另一列“扩展”一个 HIVE 查询:性能和最佳实践

Posted

技术标签:

【中文标题】用另一列“扩展”一个 HIVE 查询:性能和最佳实践【英文标题】:"Extend" a HIVE query with another column: performance and best practices 【发布时间】:2019-02-13 22:00:57 【问题描述】:

我有一个HIVE 查询,它使用GROUP BY 计算一些值。

SELECT 
  COUNT(DISTINCT user_id),
  date,
  operating_system,
  action
FROM user_actions
GROUP BY date, operation_system, action;

此查询正确返回我的第一个结果,即每天在每个平台上执行每个操作的唯一用户数。

现在,我还想计算每个操作系统每天的唯一身份用户总数,并将其添加为一列。这样,我们可以将执行每个操作的用户数与该平台/天上的用户总数进行比较。

我的尝试如下:

SELECT 
  COUNT(DISTINCT user_id),
  date,
  operating_system,
  action,
  COUNT(DISTINCT user_id) OVER (PARTITION BY operation_system, date) AS TOTAL
FROM user_actions
GROUP BY date, operation_system, action;

我想知道两者之间是否存在最佳实践。前者甚至似乎无法正常工作?我认为这是因为分区是在GROUP BY 之后计算的,而不是同时计算的。

如果是这种情况,那么根据这个:https://www.postgresql.org/docs/9.0/tutorial-window.html,我也许可以将计算总计的函数移动到子查询中,然后从中进行选择,但这似乎“hacky”。​​

【问题讨论】:

【参考方案1】:

查询

如果您想计算每个操作系统每天的唯一用户数,那么您在第一个查询中不需要action

SELECT 
  COUNT(DISTINCT user_id),
  date,
  operating_system
FROM user_actions
GROUP BY date, operation_system;

当你使用窗口聚合函数时,你就不需要group by结尾的子句了。

SELECT 
  date,
  operating_system,
  COUNT(DISTINCT user_id) OVER (PARTITION BY operation_system, date) AS TOTAL
FROM user_actions;

性能和最佳做法

这里没有通用的答案,查询的性能取决于很多东西,比如索引和连接。您需要根据您的查询要求来决定您要选择的方法。

窗口函数作用于一组行并对其进行计算。当有一个大表时,通常 子查询 不是 窗口函数 因为 子查询 需要保存所有中间结果。

在您的情况下,您使用的是 Window 聚合函数计数,如果您使用 groupby 执行此操作并不会显着改善。

【讨论】:

以上是关于用另一列“扩展”一个 HIVE 查询:性能和最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

Hive查询:根据条件选择一列,另一列值匹配某些特定值,然后将匹配结果创建为新列

Oracle - 用另一列中的值填充列中的空值

查询与 Hive QL 中另一列中的每个值关联的最短字符串值的更有效方法

用另一列中的值替换缺失值

Power Query / Power BI - 用另一列中的值替换空值

如果 NaN 用另一列替换,Pandas 将组中的最后一项替换