为了将数百万条记录添加到具有持续内存消耗的 Postgres 数据库中,我使用了一个线程池,其中包含多个工作人员以及一个gorp.Transaction
.
每百万条记录,以下代码从不同的线程调用大约一百次,每次处理一批 10000 条左右的记录:
func batchCopy(p importParams) error {
copy := pq.CopyIn("entity", "startdate", "value", "expirydate", "accountid")
stmt, err := p.txn.Prepare(copy)
if err != nil {
return err
}
for _, r := range p.records {
_, err := stmt.Exec(
r.startDate,
r.value,
r.expiryDate,
p.accountId)
if err != nil {
return err
}
}
if err := stmt.Close(); err != nil {
return err
}
return nil
}
出于某种原因,我注意到这个过程往往很慢,Prepare
并且Close
调用时间很长。
然后,我尝试对所有调用重用相同的语句,batchCopy
并在所有调用完成后关闭它。在这种情况下,batchCopy
完成速度非常快,但是当我打电话时stmt.Close()
- 它需要很长时间。
问题:
- 声明的正确方法是什么?我应该每批创建一个还是重复使用它们?
- 发生了什么事
stmt.Close()
,为什么在多次致电后需要这么长时间stmt.Exec
?