为啥今天集群/分区上的查询成本远高于以前的日期?

Posted

技术标签:

【中文标题】为啥今天集群/分区上的查询成本远高于以前的日期?【英文标题】:Why the cost of a query on today cluster/partition is much higher than on previous dates?为什么今天集群/分区上的查询成本远高于以前的日期? 【发布时间】:2019-03-17 10:40:39 【问题描述】:

我有一个分区/集群表如下:

当我运行这个查询时:

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

如您所见,今天分区的行数比前 2 天还要少

此外,我尝试使用此查询查询流式缓冲区,但未返回任何结果

SELECT projectId FROM `projectId.dataset.tables`
WHERE _PARTITIONTIME IS NULL

我的结论是流缓冲区正在影响集群表上的查询成本,但我不确定这是怎么发生的以及为什么会这样。

关于这里发生了什么以及为什么我在查询今天的分区时看到更高的成本的任何想法

【问题讨论】:

【参考方案1】:

当您对表进行聚类时,您基本上是在选择如何在存储时对其进行物理排序。

当您流式传输到表中时,新行大致按照接收到的顺序存储,因此破坏了集群的“物理排序”承诺。

BigQuery 应该足够聪明,可以不时以静默方式重新排序您的聚簇表,但如果该过程没有运行,您将看不到聚簇的好处。

根据当前发布的文档,您可以使用MERGE 强制对未排序的数据进行重新聚类:

随着时间的推移,随着越来越多的操作修改一张表,数据的排序程度开始减弱,表变成部分排序的。在部分排序的表中,与完全排序的表相比,使用聚簇列的查询可能需要扫描更多块。您可以通过运行 SELECT * 查询来重新聚集整个表中的数据,该查询从表中选择并覆盖表(或其中的任何特定分区)。此外,可以使用 DML MERGE 语句重新聚集表的任意部分。

https://cloud.google.com/bigquery/docs/clustered-tables

【讨论】:

Felipe 一如既往地感谢您,我不确定我是否完全理解您的回答。您是说在流式传输期间,数据没有按照表集群定义存储,并且 bigquery 运行批处理作业来离线构建集群?如果是这样,为什么聚类会减弱?如果今天的分区在插入/接近实时时没有优化,您是否也觉得它有点缺点,因为这通常是最易扫描的分区? 对此的回答是,这两件事不可能同时发生。至少在目前的实施水平下。请注意,集群今天处于测试状态。【参考方案2】:

更新:现在 BigQuery 对所有聚簇表执行 automatic re-clustering。

【讨论】:

以上是关于为啥今天集群/分区上的查询成本远高于以前的日期?的主要内容,如果未能解决你的问题,请参考以下文章

Bigquery 集群不会降低查询成本

从 redshift 中删除外部表的所有分区

Hive_分区表

linux 系统为啥很安全 ,不中病毒

按分区上的 MIN(日期)过滤 |数据洞察

比较两个日期分区上的同一行