为什么多个连接需要永远?

sha*_*vi2 1 google-bigquery

我相信我在Google BigQuery中发现了一个错误,但我不确定.我希望有人可以提供解决方法.

我正在一张只有200K数据的表上运行的表.

在我尝试进行漏斗分析时,我偶然发现了以下奇怪的行为:

这需要约3秒钟:

SELECT
  COUNT(DISTINCT Q0._user_id) AS step0
FROM
  (SELECT _user_id FROM [5629499534213120.201501]) AS Q0
LEFT OUTER JOIN
  (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _os=='Windows') AS Q1
ON (Q0._user_id=Q1._user_id)
Run Code Online (Sandbox Code Playgroud)

这需要约3分钟:

SELECT
  COUNT(DISTINCT Q0._user_id) AS step0
FROM
  (SELECT _user_id FROM [5629499534213120.201501]) AS Q0
LEFT OUTER JOIN
  (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _os=='Windows') AS Q1
ON (Q0._user_id=Q1._user_id)
LEFT OUTER JOIN
  (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _country=='de') AS Q2
ON (Q0._user_id=Q2._user_id)
Run Code Online (Sandbox Code Playgroud)

意味着再添加一个Left Join会使查询变得非常慢(我们只讨论了200k的数据).

显然,我已经简化了Select语句,因此您可以专注于主要问题(我使用的真正的select语句要复杂得多)

有谁知道问题是什么,或者解决方法是什么?

Jor*_*ani 5

我在BigQuery问题跟踪器上回复了这个问题,但我在这里重新发布我的答案:

我是一个很棒的工程师,我在日志中查询了你的查询.您所看到的是加入爆炸.

您使用非唯一键进行了3向自连接.字段"_user_id"具有单个值,左侧匹配3937行,第一个联接中匹配1388行,第二个联接中匹配1388行.

这意味着您要创建3937*1388*1488或75亿输出行.(然后,您对它们进行了不同的计数以减小输出大小,但需要首先创建中间值).

毫不奇怪,创建75亿个中间行需要花费几分钟,特别是因为它们都来自单个密钥,因此必须由单个工作任务生成.

我的猜测是,可以重构您的查询以避免连接爆炸.