读取BigQuery表的最佳方法

时间:2018-08-08 08:50:02

标签: google-cloud-platform google-bigquery google-cloud-dataflow apache-beam

从BigQuery读取并过滤数据,我有2种方法

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

  2. 使用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);
    }
}

1 个答案:

答案 0 :(得分:0)

根据您的用例,可以同时使用两种方式,并且您应该考虑每种选择的利弊。

第一个(读取整个表)将非常快,因为Dataflow可以轻松地将工作负载拆分为多个分片,并以并行方式对其进行处理,从而实现了快速性。缺点是,由于大量使用CPU,成本可能会更高。

由于BigQuery会执行多项操作,因此第二个选项的速度预计会比较慢,但会节省成本。此选项的弊端可能是,您将遇到一个或多个quota and limit of BigQuery,这将需要精心编写的代码才能推翻。

您还可以检查是否可以为reading the whole tableuse a string queryuse a filter method(从此StackOverflow thread汲取灵感)实现这些示例。