阅读 BigQuery 的最佳方式 Table
Best way to read BigQuery Table
读取 BigQuery 和过滤数据,我有 2 种方式
从 Dataflow 中的 BigQuery 中读取(使用 BigqueryIO.readTableRow.from(ValueProvider))整个数据,然后根据最大日期等条件进行过滤
使用 NestedValueProvider 从 Dataflow 中的 BigQuery 读取通过进行仅获取所需数据的查询要慢得多。
因为如果我读取整个数据会出现问题并且我的 Table 处于附加模式,这将增加读取数据的时间作为 Day Pass。
但是如果我只读取特定的日期数据,这将使我的管道读取时间一致。
但是对于 200 条记录,嵌套值提供程序比使用 BigqueryIO.readTableRow.from(ValueProvider) 读取整个数据花费的时间要多得多。
我错过了什么有人可以帮忙吗?
我的代码段在下面,请查找。
Snippet:
PCollection<TableRow> targetTable = input.apply("Read TRUSTED_LAYER_TABLE_DESCRIPTION", BigQueryIO
.readTableRows()
.withoutValidation()
.withTemplateCompatibility()
.fromQuery(NestedValueProvider.of(options.get(Constants.TABLE_DESCRIPTION.toString())
, new QueryTranslator(options.get(Constants.ETL_BATCH_ID.toString())))).usingStandardSql());
嵌套值提供程序Class 片段:
public class QueryTranslator implements SerializableFunction{
/**
* Read data with max etlbatchid from query
*/
ValueProvider<String> etlbatchid;
public QueryTranslator(ValueProvider<String> etlbatchid){
this.etlbatchid = etlbatchid;
}
private static final long serialVersionUID = -2754362391392873056L;
@Override
public String apply(String input) {
String batchId = this.etlbatchid.get();
if(batchId.equals("-1"))
return String.format("SELECT * from `%s`", input);
else
return String.format("SELECT * from `%s` where etlbatchid = %s;", input,batchId);
}
}
根据您的使用情况,这两种方式都可以使用,您应该考虑您选择的每一种方式的优缺点。
第一个(读取整个 table)将非常快,因为 Dataflow 可以轻松地将工作负载拆分为多个分片并并行处理,因此速度很快。缺点是由于 CPU 使用密集,成本可能会更高。
由于 BigQuery 将执行多个操作,因此预计第二个选项会更慢,但会具有成本效益。此选项的缺点是,您可能会遇到一个或多个 quota and limit of BigQuery,这需要精心编写代码才能推翻。
您还可以检查是否可以为 reading the whole table, use a string query and use a filter method (inspired from this ) 实现这些示例。
读取 BigQuery 和过滤数据,我有 2 种方式
从 Dataflow 中的 BigQuery 中读取(使用 BigqueryIO.readTableRow.from(ValueProvider))整个数据,然后根据最大日期等条件进行过滤
使用 NestedValueProvider 从 Dataflow 中的 BigQuery 读取通过进行仅获取所需数据的查询要慢得多。
因为如果我读取整个数据会出现问题并且我的 Table 处于附加模式,这将增加读取数据的时间作为 Day Pass。
但是如果我只读取特定的日期数据,这将使我的管道读取时间一致。
但是对于 200 条记录,嵌套值提供程序比使用 BigqueryIO.readTableRow.from(ValueProvider) 读取整个数据花费的时间要多得多。
我错过了什么有人可以帮忙吗?
我的代码段在下面,请查找。
Snippet:
PCollection<TableRow> targetTable = input.apply("Read TRUSTED_LAYER_TABLE_DESCRIPTION", BigQueryIO
.readTableRows()
.withoutValidation()
.withTemplateCompatibility()
.fromQuery(NestedValueProvider.of(options.get(Constants.TABLE_DESCRIPTION.toString())
, new QueryTranslator(options.get(Constants.ETL_BATCH_ID.toString())))).usingStandardSql());
嵌套值提供程序Class 片段:
public class QueryTranslator implements SerializableFunction{
/**
* Read data with max etlbatchid from query
*/
ValueProvider<String> etlbatchid;
public QueryTranslator(ValueProvider<String> etlbatchid){
this.etlbatchid = etlbatchid;
}
private static final long serialVersionUID = -2754362391392873056L;
@Override
public String apply(String input) {
String batchId = this.etlbatchid.get();
if(batchId.equals("-1"))
return String.format("SELECT * from `%s`", input);
else
return String.format("SELECT * from `%s` where etlbatchid = %s;", input,batchId);
}
}
根据您的使用情况,这两种方式都可以使用,您应该考虑您选择的每一种方式的优缺点。
第一个(读取整个 table)将非常快,因为 Dataflow 可以轻松地将工作负载拆分为多个分片并并行处理,因此速度很快。缺点是由于 CPU 使用密集,成本可能会更高。
由于 BigQuery 将执行多个操作,因此预计第二个选项会更慢,但会具有成本效益。此选项的缺点是,您可能会遇到一个或多个 quota and limit of BigQuery,这需要精心编写代码才能推翻。
您还可以检查是否可以为 reading the whole table, use a string query and use a filter method (inspired from this