BigQuery - 获取 1000000 条记录并使用 goLang 对数据进行一些处理

Posted

技术标签:

【中文标题】BigQuery - 获取 1000000 条记录并使用 goLang 对数据进行一些处理【英文标题】:BigQuery - fetch 1000000 records and do some process over data using goLang 【发布时间】:2019-05-22 03:04:09 【问题描述】:

我在 BigQuery 中有 1000000 条记录。使用goLang从数据库中获取数据和处理的最佳方法是什么?如果无限制地获取所有数据,我会遇到超时问题。我已经将限制增加到 5 分钟,但需要超过 5 分钟。 我想做一些流式调用或分页实现,但我不知道在 golang 中我该怎么做。

var FetchCustomerRecords = func(req *http.Request) *bigquery.RowIterator 
    ctx := appengine.NewContext(req)
    ctxWithDeadline, _ := context.WithTimeout(ctx, 5*time.Minute)
    log.Infof(ctx, "Fetch Customer records from BigQuery")
    client, err := bigquery.NewClient(ctxWithDeadline, "ddddd-crm")
    q := client.Query(
        "SELECT * FROM Something")

    q.Location = "US"
    job, err := q.Run(ctx)
    if err != nil 
        log.Infof(ctx, "%v", err)
    
    status, err := job.Wait(ctx)
    if err != nil 
        log.Infof(ctx, "%v", err)

    
    if err := status.Err(); err != nil 
        log.Infof(ctx, "%v", err)
    
    it, err := job.Read(ctx)

    if err != nil 
        log.Infof(ctx, "%v", err)
    
    return it

【问题讨论】:

【参考方案1】:

您可以直接读取表格内容而无需发出查询。这不会产生查询费用,并提供与从查询中获得的相同的行迭代器。

对于小的结果,这很好。对于大表,我建议查看新的storage api,以及samples page 上的代码示例。

对于一个小表或只是读取一小部分行,您可以执行以下操作(从一个公共数据集表中读取多达 10k 行):

func TestTableRead(t *testing.T) 
    ctx := context.Background()
    client, err := bigquery.NewClient(ctx, "my-project-id")
    if err != nil 
        t.Fatal(err)
    

    table := client.DatasetInProject("bigquery-public-data", "***").Table("badges")
    it := table.Read(ctx)

    rowLimit := 10000
    var rowsRead int
    for 
        var row []bigquery.Value
        err := it.Next(&row)
        if err == iterator.Done || rowsRead >= rowLimit 
            break
        

        if err != nil 
            t.Fatalf("error reading row offset %d: %v", rowsRead, err)
        
        rowsRead++
        fmt.Println(row)
    

【讨论】:

【参考方案2】:

您可以拆分查询以获得 10 倍的 100000 条记录并在多个 goroutine 中运行

使用 sql 查询 select * from somewhere order by id DESC limit 100000 offset 0

在下一个 goroutine select * from somewhere order by id DESC limit 100000 offset 100000

【讨论】:

以上是关于BigQuery - 获取 1000000 条记录并使用 goLang 对数据进行一些处理的主要内容,如果未能解决你的问题,请参考以下文章

bigquery 为每条记录转置和连接

获取 Google BigQuery 中值的最后一次更改时间

使用“列表”检索 BigQuery 的 queryResult 只得到 512 条记录

如何在 BigQuery 中找到每条记录(由 ID 标识)的所有不同值?

使用 WSO2 在 BigQuery 中插入多条记录

有没有办法让 Pub/Sub -> Dataflow -> BigQuery 模板处理每条消息的多个记录?