使用迭代器从Bigquery读取100万行比Java或kotlin慢10倍?

使用迭代器从Bigquery读取100万行比Java或kotlin慢10倍?,java,kotlin,go,google-bigquery,Java,Kotlin,Go,Google Bigquery,我的目的是使用Go查询Biquery并索引Elasticsearch中的一些字段。这将是一个一次性批处理作业。由于团队拥有Java方面的知识,我们决定对这两种语言进行基准测试。我注意到Go使用“迭代器方式”工作得很慢 为什么会有时间上的差异 我是否在Go中缺少一些客户端或查询配置,或者这是预期的行为 我怎样才能提高阅读时间 Java/kotlin和Go: 在相同的环境中运行 Bigquery数据集200GB 相同的“sql”查询,连接两个表,只检索12个ish字段。限制100万行 使用交互式查

我的目的是使用Go查询Biquery并索引Elasticsearch中的一些字段。这将是一个一次性批处理作业。由于团队拥有Java方面的知识,我们决定对这两种语言进行基准测试。我注意到Go使用“迭代器方式”工作得很慢

为什么会有时间上的差异

我是否在Go中缺少一些客户端或查询配置,或者这是预期的行为

我怎样才能提高阅读时间

Java/kotlin和Go:

  • 在相同的环境中运行
  • Bigquery数据集200GB
  • 相同的“sql”查询,连接两个表,只检索12个ish字段。限制100万行
  • 使用交互式查询运行两种语言的GCP文档中的示例代码:
(我简化了代码)

Go 1.16.3

...

type Test struct {
    TestNo    *big.Rat              `bigquery:"testNo,nullable"`
    TestId    bigquery.NullString   `bigquery:"testId"`
    TestTime  bigquery.NullDateTime `bigquery:"testTime"`
    FirstName bigquery.NullString   `bigquery:"firstName"`
    LastName  bigquery.NullString   `bigquery:"lastName"`
    Items     []ItemTest            `bigquery:"f0_"`
}

type ItemTest struct {
    ItemType  bigquery.NullString `bigquery:"itemType"`
    ItemNo    bigquery.NullString `bigquery:"itemNo"`
    ProductNo *big.Rat            `bigquery:"productNo,nullable"`
    Qty       *big.Rat            `bigquery:"qty,nullable"`
    Name      bigquery.NullString `bigquery:"name"`
    Price     *big.Rat            `bigquery:"price,nullable"`
}


ctx := context.Background()
client, err := bigquery.NewClient(ctx, projectID)
if err != nil {
    // TODO: Handle error.
}


q := client.Query(myQuery)

it, err := q.Read(ctx)
if err != nil {
    // TODO: Handle error.
}


for {
    start := time.Now().UTC()

    var t Test
    err := it.Next(&t)
    if err == iterator.Done {
        break
    }
    if err != nil {
        // TODO: Handle error.
    }

    end += time.Since(start)

    IndexToES(t)
   
}

fmt.Println(end) //13 minutes.

...

阅读并映射到Go结构需要13分钟

Kotlin

...

val start: BigDecimal = Instant.now().toEpochMilli().toBigDecimal().setScale(3)

val bigquery = BigQueryOptions.newBuilder()
            .setCredentials(credentials)
            .setProjectId(PROJECT_ID)
            .build()
            .service

val queryConfig = QueryJobConfiguration.newBuilder(query).build()

val tableResult = bigquery.query(queryConfig)

val test = results.iterateAll()
            .map { myMapper.mapToTest(it) }

val end: BigDecimal = Instant.now().toEpochMilli().toBigDecimal().setScale(3)


logResults(start, end) // 60000ms = 1minute 

fun logResults(start: BigDecimal, end: BigDecimal){
       println("query: " + (pitB - pitA).setScale(0) + "ms") 
}

//iterate through test and indexing at the same time
...


需要1分钟

这两个片段都不完整,因此不清楚这是否是苹果对苹果。如果你想知道GO程序的时间在哪里,考虑杠杆效应。< /P>
需要指出的另一点是,如果您正在读取数百万行的查询输出,那么您将需要查看。使用此迭代器而不是您当前测试的迭代器可以加快这两种语言的速度。

请阅读:我不知道答案,因为我对go了解很少(甚至更少了解它的内部结构),但这一定是
JVM
执行的奇妙方式