BigQuery:为什么从临时表中查询比整个数据集上的单个聚合花费多20倍的时间?

时间:2018-05-07 07:16:20

标签: google-bigquery

dataset.transactions包含约5.000.000条记录。

1)此查询需要约3秒钟:

SELECT *
  FROM dataset.transactions
  WHERE customer = 'c1' AND year = 2017

2)此查询大约需要10秒钟:

SELECT
  salesrep_id AS id,
  date AS lastUsedForFplDate,
  fpl AS individual_fpl,
  ANY_VALUE(salesrep_name) AS salesrep_name,
  ANY_VALUE(customer) AS customer
FROM dataset.transactions VT1
  WHERE date = (
    SELECT
      MAX(date)
    FROM dataset.transactions VT2
    WHERE
      VT1.salesrep_id = VT2.salesrep_id
  )
GROUP BY
  salesrep_id,
  date,
  fpl

3)然而这一次需要超过200秒(尝试几次,每次在200秒后取消):

WITH transactions AS (
  SELECT *
  FROM dataset.transactions
  WHERE customer = 'c1' AND year = 2017
)

SELECT
  salesrep_id AS id,
  date AS lastUsedForFplDate,
  fpl AS individual_fpl,
  ANY_VALUE(salesrep_name) AS salesrep_name,
  ANY_VALUE(customer) AS customer
FROM transactions VT1
  WHERE date = (
    SELECT
      MAX(date)
    FROM transactions VT2
    WHERE
      VT1.salesrep_id = VT2.salesrep_id
  )
GROUP BY
  salesrep_id,
  date,
  fpl

第三个查询由上面的两个查询组成,除了#2使用#1的输出作为源。

为什么需要这么多时间?

1 个答案:

答案 0 :(得分:1)

只是不要将问题留下答案。第三个查询使用自联接,这是由Elliott评论的anti pattern

  

使用自连接的结果是它可能会使输出行数增加一倍。输出数据的增加会导致性能下降。

建议不要使用自联接,而是使用window (analytic) function来减少查询生成的额外字节数。

分析函数的简化语法如下:

analytic_function_name ( [ argument_list ] )
  OVER (
    [ PARTITION BY partition_expression_list ]
    [ ORDER BY expression [{ ASC | DESC }] [, ...] ]
    [ window_frame_clause ]
  )