【问题标题】:BigQuery Cross Join Much Faster with EachBigQuery 的交叉连接速度更快
【发布时间】:2015-03-01 04:20:45
【问题描述】:

我正在尝试按日期查看用户活动。第一步是使用交叉联接和 where 子句构建自创建用户帐户以来的每一天的表。我的第一次尝试是这样的:

SELECT
  u.user_id as user_id,
  date(u.created) as signup_date,
  cal.date as date,

from rsdw.user u
  cross join (select date(dt) as date from [rsdw.calendar] where date(dt) < CURRENT_DATE() ) cal
where
  date(u.created) <= cal.date

(日历表只是自 2006 年以来所有日期的列表(3288 行)。用户表有大约 1m 行。)

这个查询需要很长时间......太长了,以至于我在 1000 秒左右就放弃了它。我试着稍微调整一下查询。如果我在交叉连接中添加一个“每个”:

SELECT
  u.user_id as user_id,
  date(u.created) as signup_date,
  cal.date as date,

from rsdw.user u
  cross join each (select date(dt) as date from [rsdw.calendar] where date(dt) < CURRENT_DATE() ) cal
where
  date(u.created) <= cal.date

我得到一个错误:

Error: Cannot CROSS JOIN two tables with EACH qualifiers.

最后,如果我保留“每个”但交换表,则只需 90 秒即可完成!

SELECT
  u.user_id as user_id,
  date(u.created) as signup_date,
  cal.date as date,

from (select date(dt) as date from [rsdw.calendar] where date(dt) < CURRENT_DATE() ) cal
  cross join each rsdw.user u
where
  date(u.created) <= cal.date

谁能解释为什么第三次迭代要快得多,为什么第二次会出错?

【问题讨论】:

    标签: google-bigquery cross-join


    【解决方案1】:

    您在连接如何与子选择子句交互时遇到了一些极端情况。针对命名表的连接受益于基于表大小的一些优化,而子选择是不可预测的并且可能导致性能不佳。我已经提交了一个内部错误供我们改进。

    在第一种缓慢的情况下,您的小日期子选择被复制并广播到少量机器,每台机器都处理大量用户。这需要很长时间,因为并行性很少。

    第二种情况是由于内部原因导致查询解析错误,基本上是试图让机器同时处理小范围的日期和小范围的用户,这样就不会完成交叉连接。

    在第三种情况下,快速的情况下,您的微小日期子选择被复制并广播到许多机器,每台机器处理一小部分用户。由于并行度很大,它完成得非常快。

    一旦我们完成了我提交的错误,第三种情况的行为有望自动发生。

    【讨论】:

      【解决方案2】:

      基于https://cloud.google.com/bigquery/query-reference,交叉连接甚至不支持“each”子句,所以我对第三个查询甚至运行感到有些惊讶。

      交叉连接形成笛卡尔积(左表中的每条记录都与右查询中的每条记录连接) - 这是一种非常低效的数据连接方式(尽管有时无法避免,例如您的方式试图创建你的数据集)。用户表中有多少条记录? EACH 子句仅在左表较小(且压缩在 8MB 以下)时才有效。您的日历表包含 3650 条记录,因此如果您的用户数超过此数量,则它需要位于左侧 - 就像您在第三个查询中所做的那样。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-01
      • 2018-09-16
      • 2016-09-13
      • 2020-03-01
      • 2023-01-24
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多