Google BigQuery 优化策略

Google BigQuery Optimization Strategies

我正在使用 Google BigQuery 从 Google Analytics Premium 查询数据。目前,我有一个查询用于计算一些指标(如总访问量或转化率)。此查询包含多个嵌套的 JOIN 子句和嵌套的 SELECT。仅查询一个 table 时出现错误:

Error: Resources exceeded during query execution.

使用 GROUP EACH BY 和 JOIN EACH 似乎不能解决这个问题。

未来要采用的一种解决方案是只提取本次查询需要的相关数据,并导出到一个单独的table(之后会被查询)。这个策略原则上是有效的,我已经有了一个工作原型。

但是,我想探索适用于原始 table 的此查询的其他优化策略。

在此演示文稿中 You might be paying too much for BigQuery 建议了其中一些,即:

书"Google BigQuery Analytics"也提到调整查询特征,即:

另一种方法是将这个查询拆分成它的组成子查询,但目前我不能选择这个策略。

我还能做些什么来优化这个查询?

Google 的 BigQuery 有很多怪癖,因为它不兼容 ANSI。这些怪癖也是它的优点。也就是说,您将浪费太多时间直接针对 BigQuery 编写查询。您应该使用 API/SDK 或 Looker 等工具,它会为您生成 SQL:https://looker.com/blog/big-query-launch-blog 在执行时,在花钱之前给您资源估算。

为什么 BigQuery 有错误?

BigQuery 是一种共享的分布式资源,因此预计作业会在某个时间点失败。这就是为什么唯一的解决方案是使用指数退避重试作业。作为一条黄金法则,作业应至少重试 5 次,只要作业无法完成超过 15 分钟,服务就在 SLA [1].

可能是什么原因?

我可以想出两个可能影响您的查询的原因:

  1. 数据倾斜[2]
  2. 未优化的查询

数据倾斜

关于第一种情况,当数据分布不均匀时会发生这种情况。因为 BigQuery 的内部机制使用 MapReduce 的一个版本,这意味着如果您有例如具有数百万点击率的音乐或视频文件,则进行数据聚合的工作人员将耗尽资源,而其他工作人员则不会做太多事情这一切都是因为他们正在处理的视频或音乐的聚合几乎没有点击率。

如果是这种情况,建议统一分发您的数据。

未优化的查询

如果您无权修改数据,唯一的解决方案是优化查询。优化查询遵循以下一般规则:

  • 使用 SELECT 时,请确保仅 select 严格需要的列,因为这会减少请求的基数(例如避免使用 SELECT *)
  • 避免对大型数据集使用 ORDER BY 子句
  • 避免使用 GROUP BY 子句,因为它们会造成并行性障碍
  • 避免使用 JOINS,因为它们会占用工作人员的内存,并可能导致资源匮乏和资源错误(如内存不足)。
  • 避免使用分析函数 [3]
  • 如果可能,请对分区表 [4] 进行查询。

遵循这些策略中的任何一个应该可以帮助您的查询减少错误并缩短总体 运行 时间。

额外

除非先了解 MapReduce,否则您无法真正了解 BigQuery。出于这个原因,我强烈建议您查看 Hadoop 教程,例如 tutorialspoint 中的教程:

对于类似版本的 BigQuery,但它是开源的(并且在各个方面都不太优化),您还可以查看 Apache Hive [4]。如果您理解 Apache Hive 失败的原因,您就会理解 BigQuery 失败的原因。

[1] https://cloud.google.com/bigquery/sla

[2]https://www.mathsisfun.com/data/skewness.html

[3]https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#analytic-functions

[4]https://cloud.google.com/bigquery/docs/partitioned-tables

[5]https://en.wikipedia.org/wiki/Apache_Hive