我有一个分区/集群表,如下所示:
当我运行此查询时:
SELECT
projectId
FROM
`projectId.dataset.tables`
WHERE _PARTITIONTIME >= "2019-03-16 00:00:00" AND _PARTITIONTIME <= "2019-03-17 00:00:00"
AND projectId='myproject'
GROUP BY
projectId
limit 1
我看到的实际扫描为 597 MB
但是,当我在前一天运行相同的查询时,如下所示:
SELECT
projectId
FROM
`projectId.dataset.tables`
WHERE _PARTITIONTIME >= "2019-03-15 00:00:00" AND _PARTITIONTIME <= "2019-03-16 00:00:00"
AND projectId='myproject'
GROUP BY
projectId
limit 1
我看到的实际扫描为 122 MB
注意:如果添加更多列,结果将更加糟糕。
为确保分区大小相同,我计算了每个分区中的projectId数量
SELECT _partitionTime as date, count(projectId) as count
FROM
`projectId.dataset.tables`
WHERE _PARTITIONTIME >= "2019-03-15 00:00:00" AND _PARTITIONTIME <= "2019-03-17 00:00:00"
GROUP BY
date
正如您所看到的,今天分区的行数比前两天还要少
此外,我尝试使用此查询查询流缓冲区,但未返回结果
SELECT projectId FROM `projectId.dataset.tables`
WHERE _PARTITIONTIME IS NULL
我的结论是流式缓冲正在影响群集表上查询的费用,但我不确定那是怎么回事以及为什么。
关于这里发生的事情以及为什么今天查询分区时为什么看到更高成本的任何想法
答案 0 :(得分:2)
对表进行群集时,基本上是在选择存储时对其进行物理排序的方式。
当您流式传输到表中时,新行将大致按接收到的顺序存储,因此违反了群集的“按物理排序”的承诺。
BigQuery应该足够聪明,可以偶尔对集群表进行无提示的重新排序,但是如果该过程没有运行,您将看不到集群的好处。
根据当前发布的文档,您可以使用MERGE
强制重新整理未排序的数据:
随着时间的流逝,随着越来越多的操作修改表,对数据进行排序的程度开始减弱,并且对该表进行了部分排序。在部分排序的表中,与完全排序的表相比,使用群集列的查询可能需要扫描更多的块。您可以通过运行SELECT *查询来重新聚集整个表中的数据,该查询从表(或表中的任何特定分区)中选择并覆盖该表。此外,可以使用DML MERGE语句重新聚集表的任意部分。
答案 1 :(得分:1)
更新:现在,BigQuery在所有群集表上执行automatic re-clustering。