BigQuery - 集群表不使用多个键减少查询大小
Posted
技术标签:
【中文标题】BigQuery - 集群表不使用多个键减少查询大小【英文标题】:BigQuery - Clustered tables not reducing query size with multiple keys 【发布时间】:2018-08-07 05:10:33 【问题描述】:我正在尝试优化我在 BigQuery 中的查询成本,并且我一直在尝试聚集表。 供参考:BigQuery - querying only a subset of keys in a table with key value schema
按单列对表进行聚类成功地减少了我的查询大小。但是,使用多列(示例显示在:https://cloud.google.com/bigquery/docs/querying-clustered-tables#sample_table_used_in_the_examples)不会导致查询大小的任何减少。
要使用文档中给出的示例,
SELECT
SUM(totalSale)
FROM
mydataset.ClusteredSalesData
WHERE
customer_id = 10000
AND product_id LIKE 'gcp_analytics%'
如果表上没有集群,这会查询整个数据集(比如 100GB),当仅由 customer_id 集群时减少到大约 10GB(在实际运行后看到,而不是在验证器上),但根本没有变化当同时被 customer_id 和 product_id 聚类时(即使在实际运行查询之后)。
我已尝试更改聚类的顺序、WHERE 子句的顺序等。似乎没有任何改变。
这是预期的行为吗? BigQuery 上的错误?还是我做错了什么?
更新: 感谢@Pentium10 指点我:https://medium.com/@hoffa/bigquery-optimized-cluster-your-tables-65e2f684594b
要使用博文中的示例,在以下两个查询中,
第一季度:
SELECT wiki, SUM(views) views
FROM fh-bigquery.wikipedia_v3.pageviews_2017
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
AND wiki = 'en'
--AND title = 'Barcelona'
GROUP BY wiki ORDER BY wiki
第二季度:
SELECT wiki, SUM(views) views
FROM fh-bigquery.wikipedia_v3.pageviews_2017
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
AND wiki = 'en'
AND title = 'Barcelona'
GROUP BY wiki ORDER BY wiki
我原以为第二季度会更便宜,因为集群是按 (wiki, title) 进行的,但情况似乎并非如此。
【问题讨论】:
所有 BigQuery 表中的数据都存储在块中。对于集群表,数据是集群的,因此一个块可能只包含单个集群的数据。扫描聚簇表时,仅对匹配的簇/块收费。如果按 customer_id 过滤已经减少到块的 1/10,则按 product_id 过滤可能不会导致更少的块。例如,如果 customer_id = 10000 已经减少到 1 个块,按 product_id 过滤不会进一步降低成本。 有道理,这就是我理解单列聚类的方式。但是,当表使用多列聚集在一起时,这是如何工作的呢?在我看来,它必须结合指定的主要和次要列的值对其进行分块,因此添加辅助 product_id 过滤器必须只过滤块的子集。 @error_magnet 阅读:medium.com/@hoffa/… @Pentium10 谢谢,没见过这个。将使用此更新我的问题。 这取决于数据的大小。 BigQuery 会尝试保持最佳的块大小。如果 customer_id 10000 的数据小于最佳块大小,则所有数据将驻留在一个块中,按 product_id 过滤将无济于事;如果数据足够大以至于它驻留在两个块中,则按 product_id 过滤可以进一步将成本从 2 降低到 1。块 1:customer_id 10000,product_id "aaa" 到 "ppp"。块 2:customer_id 10000,product_id "qqq" 到 "zzz"。 【参考方案1】:在您的查询 1 (Q1) 中 - 处理 86.1 GB
的估计成本为 0.43 美元 - 实际计费字节数 - 18.4 GB
对于第二季度 - 处理 180 GB
的估计成本为 0.90 美元 - 实际计费字节数 - 10.3 GB
对我来说听起来更便宜 :o)
但实际上,save 不仅仅是down to 10.3 GB from 18.4 GB
——它实际上是down to 10.3 GB from 38.6 GB
。这是因为在第一季度根本没有涉及title
列,而在第二季度却是!
因此,要将苹果与苹果进行比较 - 您可以添加 title
,如下所示 - 您将看到估计成本为 180 GB
- 而实际字节数计费 - 38.6 GB
第三季度:
SELECT wiki, title, SUM(views) views
FROM `fh-bigquery.wikipedia_v3.pageviews_2017`
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
AND wiki = 'en'
-- AND title = 'Barcelona'
GROUP BY wiki, title
注意/提醒:当您查询聚簇表时 - 估计仅基于分区显示(截至目前 - 我的理解是稍后这将被修复/改进)
【讨论】:
【参考方案2】:我测试了基于this post 的下一个查询,由Pentium10 建议:
SELECT wiki, SUM(views) views
FROM `fh-bigquery.wikipedia_v3.pageviews_2017`
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
AND wiki = 'en'
AND title = 'Barcelona'
GROUP BY wiki ORDER BY wiki
已处理 180.19GB(根据validator
)。运行查询时处理了 10.3GB。
SELECT wiki, SUM(views) views
FROM `fh-bigquery.wikipedia_v3.pageviews_2017`
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
AND wiki = 'en'
--AND title = 'Barcelona'
GROUP BY wiki ORDER BY wiki
已处理 86.1GB(根据validator
)。
运行查询时处理了 18.4GB。
SELECT wiki, SUM(views) views
FROM `fh-bigquery.wikipedia_v3.pageviews_2017`
WHERE DATE(datehour) BETWEEN '2017-06-01' AND '2017-06-30'
-- AND wiki = 'en'
AND title = 'Barcelona'
GROUP BY wiki ORDER BY wiki
已处理 180.19GB(根据validator
)。
运行查询时处理了 113.85GB。
一切看起来都是连贯的,因为正如 Hoffa 先生所说,集群表的“顺序很重要”(“wiki”比“title”节省更多)。
验证器仍然无法正常工作是真的,但clustered tables
是still on beta,所以我们可以期待未来的改进。
【讨论】:
聚集表的一个问题是,在运行查询之前无法提供准确的成本估算。我们使用运行时可用的信息来降低成本并提高性能。对于聚簇表,我们将尝试使此成本估算更严格,但在许多情况下,该估算只会是一个上限。以上是关于BigQuery - 集群表不使用多个键减少查询大小的主要内容,如果未能解决你的问题,请参考以下文章