在日桌上的威尔卡与时间分区

时间:2018-02-06 10:54:31

标签: google-bigquery

我尝试了解大查询(例如成本或请求的可能性)之间是否存在差异:

  • 每天创建一个表(如my_table_2018_02_06)
  • 创建一个时间分区表(my-table,按天划分时间分区)。

谢谢!

3 个答案:

答案 0 :(得分:6)

简短解释:使用通配符表查询多个表是BigQuery没有可用分区机制的建议替代方法。自然演变包括分区表的功能,目前有一个alpha版本,包括基于列的时间分区,即让用户定义哪个列(具有DATETIMESTAMP数据类型)将用于分区。

因此,目前BigQuery工程师正在为表分区添加更多新功能,而不是传统的Wildcard Tables方法,那么我建议您使用它们。

长解释:您正在比较两种实际上用于相同目的但具有不同含义的方法:

  • 通配符表: 前段时间,当表分区不是Big Query支持的功能时,通配符表是使用简明SQL查询查询多个表的方法。通配符表表示与SQL语句中指定的通配符表达式匹配的所有表的并集。但是,Wildcard Tables have some limitations,例如:
    • 不支持观点。
    • 不支持缓存结果(包含通配符表的查询在每次运行时都会收费,即使选中了“缓存结果”选项)。
    • 仅适用于原生BigQuery存储(无法使用外部表格[Bigtable,存储或驱动器])。
    • 仅适用于标准SQL。
  • 分区表: 这些是唯一的表格,按日期划分为多个细分。有很多关于how to work with Partitioned Tables的文档,关于定价,分区表中的每个分区都被视为一个独立的实体,因此如果一个分区在过去90天内没有更新,那么这些数据将被视为长期期限因此将以适当的折扣计费(正常表格会发生)。最后,分区表仍然存在,因此有更多的传入功能,例如基于列的分区,currently in alpha,您可以在this Public Issue Tracker post中跟踪其状态。另一方面,还需要考虑some current limitations
    • 每个分区表最多2500个分区。
    • 每个表每天最多20​​00个分区更新。
    • 每10秒最多50次分区更新。

因此,一般情况下,建议使用通配符表在多个表上使用分区表。但是,您应该始终考虑您的用例,并更好地了解哪种可能性符合您的要求。

答案 1 :(得分:0)

这里要添加到您的决策标准中的一件事是传统SQL和标准SQL的缓存和使用。 由于标准SQL中用于选择多个表的语法使用通配符,因此无法缓存查询结果。

有趣的是,如果使用旧版SQL,查询结果将被缓存。仅将查询转换为标准SQL会禁用缓存。 考虑这一点可能很重要,至少在某些情况下要比其他情况更多。

谢谢你, 阴霾

答案 2 :(得分:0)

不完全是时间分区,但可以从两个世界中受益 - 通配符“分区”和用于进一步分割数据的真实分区。下面是一个示例,我们首先使用数据后缀仅选择包含该特定日期的数据的表,然后我们使用表内的实际分区来进一步限制扫描的数据量。

创建第一个带数据后缀的分区表

 CREATE TABLE `test_2021-01-05` (x INT64, y INT64)
 PARTITION BY RANGE_BUCKET(y, GENERATE_ARRAY(0, 500, 1));
 insert `test_2021-01-05` (x,y) values (5,1);
 insert `test_2021-01-05` (x,y) values (5,2);
 insert `test_2021-01-05` (x,y) values (5,3);

创建第二个带数据后缀的分区表

 CREATE TABLE `test_2021-01-04` (x INT64, y INT64)
 PARTITION BY RANGE_BUCKET(y, GENERATE_ARRAY(0, 500, 1));
 insert `test_2021-01-04` (x,y) values (4,1);
 insert `test_2021-01-04` (x,y) values (4,2);

使用通配符从两个表中选择所有数据,80B的数据是整个测试集

 select * from `test_*`
 -- 80B, all the data

只从一张表中选择数据,就像按日期分区

 select * from `test_*`
 where _TABLE_SUFFIX = "2021-01-05"
 -- 48B

从一张表(我对一个日期感兴趣)和仅从一个分区中选择数据

 select * from `test_*`
 where _TABLE_SUFFIX = "2021-01-05"
 and y = 1
 -- 16B, that was the goal

从所有表中只选择一个分区中的数据

 select * from `test_*`
 where y = 1
 -- 32B, only one partition from both tables

最终目标是限制读取时扫描的数据,从而降低成本并提高性能。