【发布时间】: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`
现在的问题是:有没有办法获得物化交叉连接的性能,而无需首先实际炸毁数据并将其物化,即实时而无需开销。
我正在尝试使用一些分析功能,但找不到可以做到这一点的东西。
【问题讨论】:
标签: sql join google-bigquery