Go 的 Bigquery 客户端比 GUI 慢得多(秒 vs 毫秒)

Don*_*per 5 go google-bigquery

    q := i.client.Query(query)

    job, err := q.Run(ctx)
    if err != nil {
        <handle>
    }
    status, err := job.Wait(ctx)
    if err != nil {
        <handle>
    }
    if err = status.Err(); err != nil {
        <handle>
    }

    it, err := job.Read(ctx)
    if err != nil {
        <handle>
    }

Run Code Online (Sandbox Code Playgroud)

这是我用来查询 BigQuery 中的表的代码。该client字段属于类型*bigquery.Client

查询本身非常简单,例如:

SELECT field, another_field from some_table LIMIT K OFFSET N

Run Code Online (Sandbox Code Playgroud)

(我知道这种类型的分页不是 BQ 的最佳实践,但这是一个单独讨论的主题)。

Run调用需要 2-4 秒,而在 GUI 中查询则需要几百毫秒。

这里可能出了什么问题?官方包文档或多或少使用相同的方法与 BigQuery 交互(但有时他们会跳过这一Wait部分)

编辑:

事实证明,使用 justQuery.Read()更快:1 秒,而不是作业等待的 3-4 秒。也就是说,它仍然比 GUI 慢得多:)

2r2*_*r2w 0

您提供的示例中的Query.Read()和之间应该没有区别,因为它是相同的机制(检查源代码https://github.com/googleapis/google-cloud-go/blob/bigquery/v1.43.0/bigquery/查询.go#L370)。调用然后job.Read()Query.Read()job.Run()job.Read()

我认为,bigquery 和 GUI 的 go 客户端之间的主要区别在于读取数据的方式:在 go 客户端中,使用 Rest API 读取结果,该 API 获取分页结果(需要找到最大页面大小,但它非常小,因为http 性质)。GUI 似乎使用存储 API(docsapi docs),速度要快得多。如果您要获取大量数据,那么差异将会很大。

我通过 go 客户端进行的测试的千兆位连接吞吐量约为 2MB/s,存储 API 约为 30MB/s。

很抱歉没有提供完整的参考链接(因为收集它们需要太多时间),但我希望我已经为您指明了阅读有关 bigquery 吞吐量性能的方向。

另一个可能降低 bigquery 性能的潜在时刻是优先级(https://pkg.go.dev/cloud.google.com/go/bigquery#QueryConfig)。但默认情况下它是交互式的,如果您没有自己设置它,BatchPriority那么这不是原因。

    // Priority specifies the priority with which to schedule the query.
    // The default priority is InteractivePriority.
    // For more information, see https://cloud.google.com/bigquery/querying-data#batchqueries
    Priority QueryPriority
Run Code Online (Sandbox Code Playgroud)