0

我正在使用以下查询查询 Chrome UX 报告公共数据集,以获取一组特定于国家/地区的表随时间变化的指示指标的值。查询运行了很长时间(我在 180 秒时停止了它),因为我不知道查询的超时时间或如何判断查询是否挂起。

我正在尝试获取average_fcpaverage_fpaverage_dcl的汇总数据。我不确定我是否正确使用 BigQuery,或者是否有办法优化查询以使其运行得更快

这是我正在使用的查询。

SELECT
  _TABLE_SUFFIX AS yyyymm,
  AVG(fcp.density) AS average_fcp,
  AVG(fp.density) as average_fp,
  AVG(dcl.density) as average_dcl
FROM
  `chrome-ux-report.country_cl.*`, 
  UNNEST(first_paint.histogram.bin) as fp,
  UNNEST(dom_content_loaded.histogram.bin) as dcl,
  UNNEST(first_contentful_paint.histogram.bin) AS fcp
WHERE
  form_factor.name = 'desktop' AND
  fcp.start > 20000
GROUP BY
  yyyymm
ORDER BY
  yyyymm
4

3 回答 3

3

我不确定获得AVG()所有密度是否具有数学意义 - 但无论如何让我们这样做。

查询中更大的问题是:

  UNNEST(first_paint.histogram.bin) as fp,
  UNNEST(dom_content_loaded.histogram.bin) as dcl,
  UNNEST(first_contentful_paint.histogram.bin) AS fcp

-- 这是一个爆炸性的连接:它将一行包含 3 个数组,每个数组约 500 个元素,转换为 1.25 亿行!!!这就是查询未运行的原因。

为您提供类似结果的类似查询:

SELECT yyyymm,
  AVG(average_fcp) average_fcp,
  AVG(average_fp) average_fp,
  AVG(average_dcl) average_dcl
FROM (
  SELECT
     _TABLE_SUFFIX AS yyyymm,
    (SELECT AVG(fcp.density) FROM UNNEST(first_contentful_paint.histogram.bin) fcp WHERE fcp.start > 20000) AS average_fcp,
    (SELECT AVG(fp.density) FROM UNNEST(first_paint.histogram.bin) fp) AS average_fp,
    (SELECT AVG(dcl.density) FROM UNNEST(dom_content_loaded.histogram.bin) dcl) AS average_dcl
  FROM `chrome-ux-report.country_cl.*` 
  WHERE form_factor.name = 'desktop'  
)
GROUP BY yyyymm
ORDER BY yyyymm

好消息:这个查询在 3.3 秒内运行。

现在查询在 3 秒内运行,最重要的问题是:它在数学上有意义吗?

在此处输入图像描述


奖励:从数学上讲,这个查询对我来说更有意义,但我不是 100% 确定它:

SELECT yyyymm,
  AVG(average_fcp) average_fcp,
  AVG(average_fp) average_fp,
  AVG(average_dcl) average_dcl
FROM (
  SELECT yyyymm, origin, SUM(weighted_fcp) average_fcp, SUM(weighted_fp) average_fp, SUM(weighted_dcl) average_dcl
  FROM (
    SELECT
       _TABLE_SUFFIX AS yyyymm,
      (SELECT SUM(start*density) FROM UNNEST(first_contentful_paint.histogram.bin)) AS weighted_fcp,
      (SELECT SUM(start*density) FROM UNNEST(first_paint.histogram.bin)) AS weighted_fp,
      (SELECT SUM(start*density) FROM UNNEST(dom_content_loaded.histogram.bin)) AS weighted_dcl,
      origin
    FROM `chrome-ux-report.country_cl.*`   
  )
  GROUP BY origin, yyyymm
)
GROUP BY yyyymm
ORDER BY yyyymm

在此处输入图像描述

于 2020-01-21T21:56:30.437 回答
2

在仔细查看您的查询后,我得出结论,您正在执行的每个操作的处理时间约为 6 秒或更短。因此,我决定从每个 unnest 执行每个任务,然后使用UNION ALL方法将表附加在一起。

查询在 4 秒内运行。语法是:

SELECT
  _TABLE_SUFFIX AS yyyymm,
  AVG(fcp.density) AS average_fcp,
FROM
  `chrome-ux-report.country_cl.*`, 
  UNNEST(first_contentful_paint.histogram.bin) AS fcp
WHERE
  form_factor.name = 'desktop' AND
  fcp.start > 20000
GROUP BY
  yyyymm


UNION ALL 

SELECT
  _TABLE_SUFFIX AS yyyymm,
  AVG(fp.density) as average_fp,

FROM
  `chrome-ux-report.country_cl.*`, 
  UNNEST(first_paint.histogram.bin) as fp
WHERE
  form_factor.name = 'desktop' 
GROUP BY
  yyyymm

UNION ALL 

SELECT
  _TABLE_SUFFIX AS yyyymm,
  AVG(dcl.density) as average_dcl
FROM
  `chrome-ux-report.country_cl.*`, 
  UNNEST(dom_content_loaded.histogram.bin) as dcl
WHERE
  form_factor.name = 'desktop' 
GROUP BY
  yyyymm
ORDER BY
  yyyymm  

此外,我想指出,根据文档,建议避免过度使用通配符,选择使用日期范围并实现大型数据集结果。另外,我想指出 BigQuery将缓存结果限制为 10gb。

我希望它有帮助。

于 2020-01-21T09:37:19.127 回答
1

让我开始说BigQuery 查询超时时间很长(6 小时),因此您在这方面应该没有问题,但您可能会遇到其他错误。

我们在内部遇到了同样的问题,我们的数据集在国家/地区表中划分了数据,即使在对大量表运行查询时这些表是按时间戳分区的,不仅查询需要很长时间,而且有时它会因超出资源而失败错误。

我们的解决方案是将所有这张表聚合成一个单独的添加“国家”列,将其用作聚类列。这不仅使我们的查询得以执行,而且比我们在国家表的子集上运行相同查询作为中间步骤然后将结果组合在一起的临时解决方案更快。它现在更快、更容易、更清洁。

回到您的具体问题,我建议创建一个新表(您需要托管 $$$),它将数据集中的所有表组合为分区表。

最快的方法,不幸的是也更昂贵的方法(你会为查询扫描付费),是使用 create table 语句。

create table `project_id.dataset_id.table_id`
partition by date_month
cluster by origin
as (
select
  date(PARSE_TIMESTAMP("%Y%m%d", concat(_table_suffix, "01"), "UTC")) as date_month,
  *
from `chrome-ux-report.country_cl.*`
);

如果此查询失败,您可以在表的子集上运行它,例如where starts_with(_table_suffix, '2018'),并针对您之前创建的表运行以下查询,并使用“写入追加”处置。

select
  date(PARSE_TIMESTAMP("%Y%m%d", concat(_table_suffix, "01"), "UTC")) as date_month,
  *
from `chrome-ux-report.country_cl.*`
where starts_with(_table_suffix, '2019')

如果您注意到我还使用了聚类列,这被认为是最佳实践。

请注意谁在管理 Google 公共数据集

最好有一个公共的“chrome_ux_report”数据集,其中只有一个按日期分区并按国家/地区聚集的表。

于 2020-01-21T09:20:08.193 回答