BigQuery 账单基于未分区/非集群列的变化

问题描述 投票:0回答:1

我有一个 BigQuery 表,该表由

ts
字段 (TIMESTAMP) 分区,并由
tag
字段 (STRING) 集群。它还具有一些其他字段:
speed
(FLOAT)和
name
(STRING)

  • 当我执行

    SELECT * from table1
    时,它会按预期预测全桌计费

  • 当我执行

    SELECT * from table1 WHERE ts='xxxxx'
    时,它会按预期预测分区计费

  • 当我执行

    SELECT * from table1 WHERE tag='yyy'
    时,它预测不到满桌计费(在我的例子中约为 50%)。查询后“字节计费”与预测相同。我预计查询后计费与查询前预测有所不同。

  • 当我执行

    SELECT * from table1 WHERE name='zzz'
    时,它还预测不到全表计费(在我的例子中约为 1%),并且查询后“计费字节”与预测相同。我期待全表计费,因为我什至没有使用聚集字段作为过滤器

  • 当我执行

    SELECT * from table1 WHERE speed=5
    时,它预测全表计费和查询后计费相同。
    speed
    name
    都是非集群的,但
    name
    过滤会减少计费,而
    speed
    则不会。我预计这两个领域都会有类似的行为。

  • 当我执行

    DELETE from table1 where tag='xxx'
    时,我也会得到全桌计费。我只期待集群计费。

知道发生了什么事吗?似乎在大多数情况下,我的期望没有得到满足,所以我可能错过了一些东西..

google-bigquery
1个回答
0
投票

分区和集群的区别在于分区将表划分为段,而集群将数据排序为块。 当您在分区表上添加 where 条件时,您将获得正确的估计账单,因为它会修剪表(基本上查看该段中的数据)。然而,通过集群,您的 BQ 在运行查询之前并不知道它将扫描多少个块,因此估计可能不准确。例如,在这种情况下,您将拥有基于

ts
(分区)的多个分段,并且在每个块中您将拥有集群块。

  • 当我执行
    SELECT * from table1
    时,它预测全表
    按预期计费

这是因为您没有指定BQ扫描表中的特定段,因此它将扫描整个表。您可以做的一件事是在分区列上强制要求 where 条件。

CREATE OR REPLACE TABLE
  projectId.dataset.table 
PARTITION BY
  TIMESTAMP_TRUNC(timestamp, DAY)
  OPTIONS( require_partition_filter=TRUE )
  • 当我执行
    SELECT * from table1 WHERE ts='xxxxx'
    时,它会预测 正如预期的那样分区计费

这是因为您指定 BQ 扫描特定段而不是整个表。

  • 当我从 table1 where tag='xxx' 执行 DELETE 时,我得到了全表 计费也是如此。我只期待集群计费。

当您对表执行 DELETE 操作时,通常会导致全表计费,因为 BQ 需要扫描整个表来识别符合 DELETE 条件的行,然后需要重写整个表来删除这些行。

  • 当我表演
    SELECT * from table1 WHERE tag='yyy'
    时, 预测不到满桌计费(在我的例子中约为 50%)。 查询后“字节计费”与预测相同。我曾是 期望查询后计费与查询前预测不同。

集群降低了成本。文档称,通过聚类,您可能无法获得准确的估计,但 BQ 会尝试仅扫描相关部分,因此有时可能是准确的。

  • 当我表演
    SELECT * from table1 WHERE name='zzz'
    时,它也 预测不到满桌的账单(在我的例子中约为 1%),并且 同样,查询后“字节计费”与预测相同。我 期待全表计费,因为我什至没有使用集群 字段作为过滤器

BQ 还有其他优化性能的方法,例如缓存。如果您运行类似的查询,BigQuery 可能会使用缓存的结果来减少扫描的数据量,而当您按速度过滤时,情况可能并非如此。

© www.soinside.com 2019 - 2024. All rights reserved.