BigQuery 表设计最佳实践:日期分区和分片的组合?

Posted

技术标签:

【中文标题】BigQuery 表设计最佳实践:日期分区和分片的组合?【英文标题】:BigQuery table design best practices: combination of date partitioning and sharding? 【发布时间】:2020-03-24 18:28:10 【问题描述】:

我们正在将我们的本地 Oracle 数据库迁移到云端。最大的项目是移动我们跟踪客户交易的事实表。

简短问题:由于 4,000 个分区限制,当您无法使用日期字段进行分区时,在 BigQuery 中对事实表进行分片/分区的最佳方法是什么?目标是最大化查询性能和最小化成本。


详细问题 我不想在 BigQuery 中复制表,因为我希望它针对 BigQuery 进行优化。所以我一直在研究分区、分片和集群。也在研究非规范化,但这是一个不同的问题。

在我们的 Oracle 数据库中,我们只需按整数日期 YYYYMMDD 进行分区。但是,我不相信我们可以在 BigQuery 中做到这一点,因为一个表只能有 4,000 个分区。如果我们按天进行分区,我们的表只能包含不到 11 (4000/365) 年的数据——这远低于我们目前需要迁移的数据。

除了日期之外,我们当然可以划分其他字段(例如站点位置),但我相信日期可能是最好的。

以下是我正在考虑的选项。假设该表包含datetimeorder_date 和整数日期版本order_date_id

    按年分片(即2001年所有带有order_date的订单进入my_table_2001,每个表按order_date分区 没有分片,有一个大表,并为年份创建一个整数列(order_year)并将其用于分区列 按另一列(例如站点位置)分片,然后按order_year 分区 按order_year 分片 另一列(例如站点位置),按order_date 分区

如果我要分表,我肯定想使用datetime 列进行分区,这样我就可以使用通配符来查询所有分表。我发现使用整数范围进行分区会阻止您使用通配符。

另外需要注意的是,如果不是所有可用数据,业务用户可能希望始终如一地查询大日期范围的数据。

【问题讨论】:

这是一个很好的问题 - 您是否已经考虑过这个问题? ***.com/questions/58743050/… 我和 Felipe Hoffa 一起建议查看集群,如果您可以完全控制查询,请使用按月分区和按日期集群的组合。 【参考方案1】:

可以考虑使用整数范围分区表: https://cloud.google.com/bigquery/docs/creating-integer-range-partitions

这是最近 GA 发布的功能。 您可以将整数日期 (YYYYMMDD) 拆分为两列:YYYYMM 和 DD,然后在 YYYYMM 上进行分区,这样您就可以拥有 4000/12 = 333 个分区。 如果您需要查询一天,您可以在查询中设置 where 子句。 为了节省查询成本,最佳做法是仅选择感兴趣的列并设置 where 子句(如果可能)。

【讨论】:

我认为使用整数范围作为分区字段的主要问题是我无法使用通配符查询表。 你能写一个查询的例子吗?我需要更好地理解你的意思 当我尝试按年份分表并按整数日期列分区时,我无法执行这样的查询来查询从 2000 年到 2009 年的所有表:select * from `my_table_200* 但是如果你说按月分区作为日期时间类型,那么我就不必分片了,因为我有 333 年的分区价值 对 Claudio 方法的一个可能补充是在 order_date 列上也对表进行聚类。当您查询表时,您使用 order_date_id 过滤到一个月,并使用 order_date 过滤到仅与日期相关的数据。如果您仍想进行时间分区,您还可以使用 order_date_month,它会将 order_date 截断为每月的第一天。

以上是关于BigQuery 表设计最佳实践:日期分区和分片的组合?的主要内容,如果未能解决你的问题,请参考以下文章

日期分区或日期分片

Big Query 中的表未分区

是否有元数据表来检查 BigQuery 中的表是否已分区?

将时间分区添加到表的最佳实践

使用 bigquery 和单个查询进行分区,根据日期将表拆分为多个表

需要关于基于非日期列和日期分区在 bigquery 中拆分表的建议