【发布时间】:2019-07-09 12:26:51
【问题描述】:
假设我有一个 BigQuery 表“事件”(实际上这是一个缓慢的子查询),它按事件类型存储每天的事件计数。事件的类型很多,而且大多数都不会在大多数日子发生,因此只有一行非零计数的日期/事件类型组合。
我有一个查询,它返回 N 天前每种事件类型和日期的计数以及该事件的计数,如下所示:
WITH events AS (
SELECT DATE('2019-06-08') AS day, 'a' AS type, 1 AS count
UNION ALL SELECT '2019-06-09', 'a', 2
UNION ALL SELECT '2019-06-10', 'a', 3
UNION ALL SELECT '2019-06-07', 'b', 4
UNION ALL SELECT '2019-06-09', 'b', 5
)
SELECT e1.type, e1.day, e1.count, COALESCE(e2.count, 0) AS prev_count
FROM events e1
LEFT JOIN events e2 ON e1.type = e2.type AND e1.day = DATE_ADD(e2.day, INTERVAL 2 DAY) -- LEFT JOIN, because the event may not have occurred at all 2 days ago
ORDER BY 1, 2
查询很慢。 BigQuery best practices 建议使用窗口函数而不是自连接。有没有办法在这里做到这一点?如果每天有一行,我可以使用LAG 函数,但没有。我可以以某种方式“填充”它吗? (没有可能的事件类型的简短列表。我当然可以加入SELECT DISTINCT type FROM events,但这可能不会比自加入更快。)
【问题讨论】:
-
这有多慢?如果您有数千天和数百个事件,那么您的表仍然很小。我希望查询会相当快。
-
在实际应用中,它不是一个表,而是一个子查询。编辑问题来说明这一点。 (我试图保持简单)。整个查询大约需要 5-6 秒。
标签: sql performance google-bigquery window-functions self-join