对于小尺寸的表,BigQuery连接速度太慢

时间:2018-06-05 06:41:27

标签: google-bigquery

我有一张表格,内容如下:
- 表尺寸39.6 MB
- 行数691,562
- 2列:contact_guid STRING,program_completed STRING
- 第1列数据类型与uuid类似。大约30个字符长度
- 第2列数据类型是大约50个字符长度的字符串

我正在尝试此查询:

#standardSQL
SELECT
  cp1.contact_guid AS p1,
  cp2.contact_guid AS p2,
  COUNT(*) AS cnt
FROM
  `data.contact_pairs_program_together`  cp1
JOIN
  `data.contact_pairs_program_together`  cp2
ON
  cp1.program_completed=cp2.program_completed
WHERE
  cp1.contact_guid < cp2.contact_guid
GROUP BY
  cp1.contact_guid,
  cp2.contact_guid having cnt >1 order by cnt desc

执行时间:1200秒

我知道我正在进行自我加入,并且在最佳做法中提到了避免自我加入。

我的问题:

  1. 我认为这个表格大小以mb为单位对于BigQuery来说太小了,所以为什么要花这么多时间?小表在连接上下文中对于行数和大小(以字节为单位)的含义是什么意思?
  2. 行数是否过大?在连接期间,700k ^ 2是10 ^ 11行。连接的实际行数是多少?
  3. 我确实检查了有关连接的文档,但没有发现关于连接的表有多大以及可以运行多长时间。我们如何估计粗略的执行时间?
  4. 执行细节: enter image description here enter image description here

2 个答案:

答案 0 :(得分:1)

如您提供的屏幕截图所示 - 您正在处理爆炸式连接。

在这种情况下,第3步需要130万行,并且可以产生4.59亿行。步骤04到0B处理所有额外数据的重新分区和重新洗牌 - 因为查询没有提供足够的资源来处理这些行数:它从1个并行输入扩展到10,000个!

这里有两个选择:要么避免爆炸连接,要么假设爆炸连接需要很长时间才能运行。但正如问题中所解释的那样 - 你已经知道了!

如果在一个op中生成所有额外的行(执行join,materialize)然后运行另一个查询来处理459万行,该怎么办?由于解释的原因,第一个查询会很慢,但第二个查询会很快运行,因为BigQuery会提供足够的资源来处理这些数据。

答案 1 :(得分:0)

同意以下建议

  

看看你是否可以使用分析函数(由Tim)重新编写查询

  
  

使用分析函数会更好(Elliott)

以下是我如何制作

#standardSQL
SELECT
  p1, p2, COUNT(1) AS cnt
FROM (
  SELECT
    contact_guid AS p1, 
    ARRAY_AGG(contact_guid) OVER(my_win) guids
  FROM `data.contact_pairs_program_together` 
  WINDOW my_win AS (
    PARTITION BY program_completed 
    ORDER BY contact_guid DESC 
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
  )
), UNNEST(guids) p2
GROUP BY p1, p2
HAVING cnt > 1
ORDER BY cnt DESC   

如果有帮助,请尝试通知我们