在聚集字段上使用 WHERE 子句运行查询时,Google BigQuery 聚集表不会减少查询大小
Posted
技术标签:
【中文标题】在聚集字段上使用 WHERE 子句运行查询时,Google BigQuery 聚集表不会减少查询大小【英文标题】:Google BigQuery clustered table not reducing query size when running query with WHERE clause on clustered field 【发布时间】:2018-10-05 16:20:23 【问题描述】:我有一个包含 500,000 行的 Google BigQuery 表,我已将其设置为由一个名为 Date 的 TIMESTAMP 字段进行分区,并由一个名为 EventCategory 的 STRING 字段进行聚类(这只是一个超过 5 亿行的表的示例)。
我有一个未分区且未聚集的表的副本。
我在两个表上运行以下查询:
SELECT
*
FROM
`table_name`
WHERE
EventCategory = "email"
只有 2400 行 EventCategory 是“电子邮件”。当我在非聚集表上运行查询时,我得到以下信息:
当我在聚簇表上运行查询时,我得到以下信息:
这里是非聚簇表和聚簇表的架构:
Date TIMESTAMP NULLABLE
UserId STRING NULLABLE
EventCategory STRING NULLABLE
EventAction STRING NULLABLE
EventLabel STRING NULLABLE
EventValue STRING NULLABLE
这两个查询之间基本上没有区别,它们查看了多少数据,我似乎无法弄清楚为什么?我已经确认集群表是分区和集群的,因为在 BigQuery UI 中的表详细信息中它实际上是这样说的,并且通过按日期过滤运行查询大大减少了搜索数据的大小,并显示估计的查询大小要小得多。
这里的任何帮助将不胜感激!
更新:
如果我将查询更改为:
SELECT
*
FROM
`table_name`
WHERE
EventCategory = "ad"
我得到以下结果:
有 53640 行 EventCategory 是“广告”,看起来集群确实导致扫描的表数据减少,尽管少不了多少(529.2MB 与 586MB 相比)。
所以看起来集群正在工作,但表中的数据没有正确集群?我将如何解决这个问题?我曾尝试使用 DDL 多次重新创建表,甚至将表数据保存到 GCS 中的 JSON,然后将其导入到新的分区和聚集表中,但它没有任何改变。
日期分区是否位于集群之上?这意味着 BigQuery 首先按日期分组,然后按这些日期组中的集群分组?如果是这样,我认为这可能会解释它,但它会使聚类不是很有用。
【问题讨论】:
您能告诉我们您的表的架构吗?也可能是您的所有数据都在同一个集群中,并且集群无法正常工作。 @Pentium10 我在上面的问题中添加了表模式。在这个 500K 行的 EventCategory 表数据中有 5 个不同的可能值。我选择的(“电子邮件”)是最小的,只有 2800 行,其中 EventCategory 是“电子邮件”。 这张表是如何“碎片化”的?尝试使用一次性选择 * 将表重新创建到同一个表中,然后再次运行 @MikhailBerlyant 我按照你的建议做了,但结果相同。 我的最后一条评论是回复我们的更新 :o) 我还要注意 - 聚类将有助于处理大量数据 - 在您的示例中并非如此(我认为是) 此外,如果您经常更新您的表 - 数据被“碎片化”(从托管的角度来看),因此集群效率较低 - 并且需要通过(例如)选择 * 到同一个表中进行碎片整理 【参考方案1】:如果您每天的数据少于 100MB,则集群对您没有多大帮助 - 您每天可能会获得一个
你没有提到你有多少天的数据(分区数,正如 Mikhail 所问的那样),但由于扫描的总数据是 500MB,我猜你至少有 5 天的数据,而且更少每天超过 100MB。
因此,您得到的结果似乎是预期的结果。
在此处查看此示例:
How can I improve the amount of data queried with a partitioned+clustered table?【讨论】:
【参考方案2】:集群没有太大帮助的原因是特定于表数据。该表是基于事件的数据,按天分区,然后按 EventCategory 进行聚类(数据在每天的分区上进行聚类)。由于每天每个 EventCategory 类型都会有大量的行,查询整个表的特定 EventCategory 仍然需要搜索每个分区,然后几乎肯定会有一些具有该 EventCategory 的数据,这意味着几乎每个集群都必须也被搜索。
【讨论】:
【参考方案3】: 数据按天进行分区,并在内部进行聚类, 当您一次加载整个分区(天)或将分区(天)导出到 Google 存储(应该是免费的)并再次将其导入另一个表时,集群效果最佳,当我们尝试加载类似 4GB JSONS 的内容时差异大约是 60/10。【讨论】:
以上是关于在聚集字段上使用 WHERE 子句运行查询时,Google BigQuery 聚集表不会减少查询大小的主要内容,如果未能解决你的问题,请参考以下文章