BigQuery 整数分区 - 我可以使用另一个查询的结果来获取要访问的分区列表吗?

Posted

技术标签:

【中文标题】BigQuery 整数分区 - 我可以使用另一个查询的结果来获取要访问的分区列表吗?【英文标题】:BigQuery Integer Partitions - can I use the results of another query to get a list of the partitions to access? 【发布时间】:2020-03-27 21:28:58 【问题描述】:

我有一个使用整数分区 (~1TB) 的大表。我需要定期制作这张表的几个小子集。这花费了很多,但使用整数分区我可以将成本降低 95%。它看起来像这样。

tbl_a : partition_index IN (1, 2, 5, 6, 7, 10, 11, 15, 104, 106, 111)

tbl_b : partition_index IN (3, 4, 5, 20, 21, 25, 16, 84, 201, 301, 302, 303)

依此类推,不同的子表使用不同的索引子集。它丑得要命,但它确实有效。我担心如果我需要创建一个新的子表,这将难以维护,并且潜在的排列发生了变化,我必须编辑所有 .sql 文件以获取新的索引值集。我有一个小表,其中包含我想要的标准的所有不同排列,以及相关的索引值。使用实际的子表选择标准对该索引查找表进行 5Kb 查询会生成索引值列表,如果将其复制并粘贴到 .sql 文件中,则可以保持一切正常运行。

但是,出于架构原因,我无法从子查询中提取索引值并在执行之前将它们作为字符串插入到 .sql 文件中。我的意思是,我可以,而且会奏效。但它的hacky和糟糕且不合理的解决方案。但是,我找不到正确使用查找表上的小查询结果的方法。它总是导致全表扫描。这里有什么想法吗?

我想一个等效的问题是,如果我有一个按 customerID 分区的大数据表,但我只有客户名称。 BQ 似乎希望我查询名称查找表以获取 ID,然后使用 customerID 作为字符串文字提交第二个查询。我希望能够在单个查询中执行此操作。但我被难住了。

【问题讨论】:

我可能不完全了解您的情况,但是将您的各种索引列表放入表中然后加入是否有用? 如果您只想运行一个小查询来确定分区过滤器,请尝试编写脚本,在这里查看我的答案:***.com/questions/51611522/… 【参考方案1】:

让我重现你的问题。

SELECT MAX(views) max_views
FROM `fh-bigquery.wikipedia_v3.pageviews_2019` 
WHERE DATE(datehour) IN ('2019-03-27', '2019-04-10', '2019-05-10', '2019-10-10')
AND wiki='en'
AND title = 'Barbapapa'

已处理 1.4GB。

但是现在你有一个包含这些日期的表格:

CREATE TABLE temp.some_dates AS (
  SELECT * 
  FROM UNNEST([DATE('2019-03-27'), '2019-04-10', '2019-05-10', '2019-10-10']) date
);

现在我们将运行一个从该表中取出值的查询:

SELECT MAX(views) max_views
FROM `fh-bigquery.wikipedia_v3.pageviews_2019` 
WHERE DATE(datehour) IN (SELECT * FROM temp.some_dates)
AND wiki='en'
AND title = 'Barbapapa'

已处理 1.4 GB。

这里没问题:处理了相同数量的数据!为什么?此表已聚集,请将您的表聚集在一起。

https://medium.com/google-cloud/bigquery-optimized-cluster-your-tables-65e2f684594b

但是让我们看看那个表的 v2,如果事情没有聚集:

SELECT MAX(views) max_views
FROM `fh-bigquery.wikipedia_v2.pageviews_2019` 
WHERE DATE(datehour) IN ('2019-03-27', '2019-04-10', '2019-05-10', '2019-10-10')
AND wiki='en'
AND title = 'Barbapapa'

已处理 26.5 GB。这远远超过 1.4GB。如果我只对这张表进行聚类。

如果我们从不同的表中获取日期呢?

SELECT MAX(views) max_views
FROM `fh-bigquery.wikipedia_v2.pageviews_2019` 
WHERE DATE(datehour) IN (SELECT * FROM `temp.some_dates`)
AND wiki='en'
AND title = 'Barbapapa'

2.3 TB。

哇,这是一个非常大的表扫描。我应该聚集我的表。

但是我能以某种方式解决这个问题吗?

是的:

DECLARE some_dates ARRAY<DATE> DEFAULT (SELECT ARRAY_AGG(date) FROM `temp.some_dates`);


SELECT MAX(views) max_views
FROM `fh-bigquery.wikipedia_v2.pageviews_2019` 
WHERE DATE(datehour) IN UNNEST(some_dates)
AND wiki='en'
AND title = 'Barbapapa'

已处理 26.46 GB。

不如聚簇表好,但至少我们使用了分区,这要归功于 BigQuery 中运行的脚本:首先声明一个变量,然后使用它的内容。

不过,我最好的建议是:将您的表聚集在一起。

https://medium.com/google-cloud/bigquery-optimized-cluster-your-tables-65e2f684594b

【讨论】:

感谢您的回复。你在这里给了我一些好主意。当我测试整数索引表时,我没有打扰集群,因为我认为集群只有在对聚集列进行过滤或执行操作时才有帮助,如果唯一的操作是在分区列上,那么我没有看到它是如何实现的会有帮助的。 如果它帮助或解决了问题,记得点赞并接受:)

以上是关于BigQuery 整数分区 - 我可以使用另一个查询的结果来获取要访问的分区列表吗?的主要内容,如果未能解决你的问题,请参考以下文章

Bigquery 整数范围分区

JavaScript 中的 BigQuery 用户定义函数不会修剪分区

从 SQL 查询向 BigQuery 表添加多个分区列

BigQuery:计算每日分区表中的平均值

如果一个数组包含使用 BigQuery 的另一个数组的所有值,我如何过滤行?

我可以一次替换 BigQuery 分区表的分区间隔吗?