阅读 BigQuery 的最佳方式 Table

Best way to read BigQuery Table

读取 BigQuery 和过滤数据,我有 2 种方式

  1. 从 Dataflow 中的 BigQuery 中读取(使用 BigqueryIO.readTableRow.from(ValueProvider))整个数据,然后根据最大日期等条件进行过滤

  2. 使用 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 ) 实现这些示例。