决定何时在 BigQuery 中对 table 进行分区的最佳平衡点是什么?
What's a good balance to decide when to partition a table in BigQuery?
我们正在使用 public 数据集来对 BigQuery 进行基准测试。我们采用相同的 table 并按天对其进行分区,但不清楚我们是否获得了很多好处。什么是好的平衡?
SELECT sum(score)
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
WHERE creation_date > "2019-01-01"
耗时 1 秒,处理 270.7MB。
相同,分区:
SELECT sum(score)
FROM `temp.questions_partitioned`
WHERE creation_date > "2019-01-01"
耗时 2 秒,处理 14.3 MB。
所以我们看到处理的 MB 有好处,但查询速度较慢。
决定何时分区的好策略是什么?
(来自我今天收到的一封电子邮件)
对table进行分区时,需要考虑每个分区有足够的数据。将每个分区想象成一个不同的文件 - 打开 365 个文件可能比打开一个大文件要慢。
在这种情况下,用于基准测试的 table 有 1.6 GB 的 2019 年数据(截至今年 6 月)。每个每日分区有 1.6GB/180 = 9 MB 的数据。
对于如此低的数据量 - 将其安排在日常分区中不会带来太多好处。考虑改为按年份对数据进行分区。请参阅以下问题以了解操作方法:
另一种方法是根本不对 table 进行分区,而是使用聚类按日期对数据进行排序。然后 BigQuery 可以选择每个块的理想大小。
如果您想 运行 自己的基准测试,请执行以下操作:
CREATE TABLE `temp.questions_partitioned`
PARTITION BY DATE(creation_date)
AS
SELECT *
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
对比没有分区,只是按日期聚类:
CREATE TABLE `temp.questions_clustered`
PARTITION BY fake_date
CLUSTER BY creation_date
AS
SELECT *, DATE('2000-01-01') fake_date
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
然后我对集群 table 的查询将是:
SELECT sum(score)
FROM `temp.questions_clustered`
WHERE creation_date > "2019-01-01"
用了 0.5 秒,处理了 17 MB。
比较:
- 原始 table:1 秒,270.7MB
- 分区:2 秒,14.3 MB
- 集群:0.5 秒,17 MB
我们有一个赢家!聚类将每日数据(对于此 table 来说并不多)组织成比按天严格划分更有效的块。
查看这些 table 上每个查询的执行详细信息也很有趣:
消耗的槽时间
- 原始 table:10.683 秒
- 分区:7.308 秒
- 集群:0.718 秒
如您所见,对 raw table 的查询使用了很多槽(并行性)以在 1 秒内获得结果。在这种情况下,50 名工作人员处理了具有多年数据的整个 table,读取了 1770 万行。分区 table 上的查询必须使用大量槽 - 但这是因为每个槽都分配了较小的每日分区,读数使用了 153 个并行工作器超过 90 万行。相反,集群查询能够使用非常少量的槽。数据组织良好,可供 57 个并行工作人员读取,读取 1.12M 行。
另请参阅:
我们正在使用 public 数据集来对 BigQuery 进行基准测试。我们采用相同的 table 并按天对其进行分区,但不清楚我们是否获得了很多好处。什么是好的平衡?
SELECT sum(score)
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
WHERE creation_date > "2019-01-01"
耗时 1 秒,处理 270.7MB。
相同,分区:
SELECT sum(score)
FROM `temp.questions_partitioned`
WHERE creation_date > "2019-01-01"
耗时 2 秒,处理 14.3 MB。
所以我们看到处理的 MB 有好处,但查询速度较慢。
决定何时分区的好策略是什么?
(来自我今天收到的一封电子邮件)
对table进行分区时,需要考虑每个分区有足够的数据。将每个分区想象成一个不同的文件 - 打开 365 个文件可能比打开一个大文件要慢。
在这种情况下,用于基准测试的 table 有 1.6 GB 的 2019 年数据(截至今年 6 月)。每个每日分区有 1.6GB/180 = 9 MB 的数据。
对于如此低的数据量 - 将其安排在日常分区中不会带来太多好处。考虑改为按年份对数据进行分区。请参阅以下问题以了解操作方法:
另一种方法是根本不对 table 进行分区,而是使用聚类按日期对数据进行排序。然后 BigQuery 可以选择每个块的理想大小。
如果您想 运行 自己的基准测试,请执行以下操作:
CREATE TABLE `temp.questions_partitioned`
PARTITION BY DATE(creation_date)
AS
SELECT *
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
对比没有分区,只是按日期聚类:
CREATE TABLE `temp.questions_clustered`
PARTITION BY fake_date
CLUSTER BY creation_date
AS
SELECT *, DATE('2000-01-01') fake_date
FROM `fh-bigquery.Whosebug_archive.201906_posts_questions`
然后我对集群 table 的查询将是:
SELECT sum(score)
FROM `temp.questions_clustered`
WHERE creation_date > "2019-01-01"
用了 0.5 秒,处理了 17 MB。
比较:
- 原始 table:1 秒,270.7MB
- 分区:2 秒,14.3 MB
- 集群:0.5 秒,17 MB
我们有一个赢家!聚类将每日数据(对于此 table 来说并不多)组织成比按天严格划分更有效的块。
查看这些 table 上每个查询的执行详细信息也很有趣:
消耗的槽时间
- 原始 table:10.683 秒
- 分区:7.308 秒
- 集群:0.718 秒
如您所见,对 raw table 的查询使用了很多槽(并行性)以在 1 秒内获得结果。在这种情况下,50 名工作人员处理了具有多年数据的整个 table,读取了 1770 万行。分区 table 上的查询必须使用大量槽 - 但这是因为每个槽都分配了较小的每日分区,读数使用了 153 个并行工作器超过 90 万行。相反,集群查询能够使用非常少量的槽。数据组织良好,可供 57 个并行工作人员读取,读取 1.12M 行。
另请参阅: