使用 Google BigQuery 上的开始/结束日期优化活动帐户查询

Posted

技术标签:

【中文标题】使用 Google BigQuery 上的开始/结束日期优化活动帐户查询【英文标题】:Optimize Active Accounts Query with Start / End Date on Google BigQuery 【发布时间】:2018-03-16 20:13:10 【问题描述】:

我希望优化查询以获取每个间隔(天、周等)的活动帐户,其中活动是在帐户的开始和结束日期定义的。布局如下:

accounts: account_id Int subscription_start Timestamp subscription_end Timestamp -- null if still active

我尝试了几种方法,最快的方法是使用 generate_array 为活动天数创建数组,然后将它们取消嵌套(大约 2 分钟)

with nested_dates as (
  select GENERATE_DATE_ARRAY(DATE(subscription_start), IFNULL(date(subscription_end), current_date()), INTERVAL 1 DAY) as dates
  from `accounts`
),
all_dates as (
  select date_item from nested_dates, UNNEST(dates) as date_item
)
select date_item, count(1) from all_dates group by date_item

我还每天使用一个子选择,在 6 到 9 个月前,当 BigQuery 仍然具有性能等级并且在 CPU 方面有更多的余地时,它曾经在类似情况下表现得相当好。但现在似乎更严格/效率更低,因为他们取消了更高的计算层定价。此执行大约需要 12 分钟。

select
  day,
  (select 
     count(1) 
   from `accounts` where
     subscription_start <= day and 
     (subscription_end is null or subscription_end >= day)
  )
from unnest(
    generate_date_array(date('2015-06-01'), current_date(), interval 1 day)
) AS day

我还使用生成日期和条件总和对帐户的交叉连接进行了性能测试(由于超出 CPU 限制,3300 秒后失败)。

当我为每个活跃的帐户生成一个所有日子的物化表时,如果我可能更快地实现分区(例如,通过使用来自第一个查询“all_dates”。

select date(day_active), count(1) from `account_all_dates`

现在的问题是:有没有办法获得物化交叉连接的性能,而无需首先实际炸毁数据并将其物化,即实时而无需开销。

我正在尝试使用一些分析功能,但找不到可以做到这一点的东西。

【问题讨论】:

【参考方案1】:

我认为您的第一个查询非常完美,并且是一种方法 它已经是最通用的,适用于任何时间间隔(天、周等),并且在所有非物化选项中都适用——最快的一个

唯一的潜在改进(而且更紧凑)如下(在我使用虚拟数据进行的快速测试中,它不断显示出稍微快一点的结果 - 但我不能肯定 - 看到你的结果会很有趣真实数据)

#standardSQL
SELECT date_item, COUNT(1) active_accounts 
FROM `accounts`, 
UNNEST(GENERATE_DATE_ARRAY(DATE(subscription_start), 
  IFNULL(DATE(subscription_end), CURRENT_DATE()), INTERVAL 1 DAY)) date_item
GROUP BY date_item

【讨论】:

感谢您的反馈,您的版本稍好一些(~10%*),我仍然希望以某种方式获得更好的结果,我正在尝试通过分析功能完成它,但是还没有找到合适的组合。 *好奇地看到它的性能稍微好一点,我希望查询编译器将它翻译成同一个作业,如果我检查它实际具有的执行计划,因为它具有完全相同的阶段和行数/大小。 我玩了一点窗口/分析函数 - 但性能明显较慢 - 所以我放弃了针对您的具体情况的这个方向

以上是关于使用 Google BigQuery 上的开始/结束日期优化活动帐户查询的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 上的提取作业不能确保 Google 存储上的文件

Google BigQuery 上的最佳 JOIN 性能

加入 Google Bigquery

在 Google BigQuery 中限制存储使用量

如何使用服务帐户确定 Google BigQuery 作业的状态?

将 BigQuery 查询结果行写入 csv 文件时,某些记录重复