从BigQuery读取并过滤数据,我有2种方法
在数据流中从BigQuery读取(使用BigqueryIO.readTableRow.from(ValueProvider))整个数据,然后根据条件(例如最大日期)进行过滤
使用NestedValueProvider从Bigflow读取数据流,方法是进行查询,该查询只会获取所需的数据,因此速度要慢得多。
由于如果我读取全部数据并且我的表处于附加模式下将会出现问题,这将增加读取数据的时间,因为这是一日游。
但是,如果我仅读取特定日期数据,这将使我的管道读取时间保持一致。
但是对于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());
嵌套值提供程序类代码段:
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);
}
}
答案 0 :(得分:0)
根据您的用例,可以同时使用两种方式,并且您应该考虑每种选择的利弊。
第一个(读取整个表)将非常快,因为Dataflow可以轻松地将工作负载拆分为多个分片,并以并行方式对其进行处理,从而实现了快速性。缺点是,由于大量使用CPU,成本可能会更高。
由于BigQuery会执行多项操作,因此第二个选项的速度预计会比较慢,但会节省成本。此选项的弊端可能是,您将遇到一个或多个quota and limit of BigQuery,这将需要精心编写的代码才能推翻。
您还可以检查是否可以为reading the whole table,use a string query和use a filter method(从此StackOverflow thread汲取灵感)实现这些示例。