我在 Golang 中运行查询,从我的 Postgresql 数据库中选择多行。
我正在为我的查询使用以下导入
"database/sql"
"github.com/lib/pq"
我已经缩小到我的循环,以便将结果扫描到我的结构中。
// Returns about 400 rows
rows, err = db.Query('SELECT * FROM infrastructure')
if err != nil {
return nil, err
}
var arrOfInfra []model.Infrastructure
for rows.Next() {
obj, ptrs := model.InfrastructureInit()
rows.Scan(ptrs...)
arrOfInfra = append(arrOfInfra, *obj)
}
rows.Close()
上面的代码运行大约需要 8 秒,虽然查询速度很快,但 rows.Next() 中的循环需要整个 8 秒才能完成。
有任何想法吗?我做错了什么,还是有更好的方法?
我的数据库配置
// host, port, dbname, user, password masked for obvious reasons
db, err := sql.Open("postgres", "host=... port=... dbname=... user=... password=... sslmode=require")
if err != nil {
panic(err)
}
// I have tried using the default, or setting to high number (100), but it doesn't seem to help with my situation
db.SetMaxIdleConns(1)
db.SetMaxOpenConns(1)
更新 1:
我将打印语句放在 for 循环中。下面是我更新的片段
for rows.Next() {
obj, ptrs := model.InfrastructureInit()
rows.Scan(ptrs...)
arrOfInfra = append(arrOfInfra, *obj)
fmt.Println("Len: " + fmt.Sprint(len(arrOfInfra)))
fmt.Println(obj)
}
我注意到在这个循环中,它实际上会中途暂停,并在短暂休息后继续。它看起来像这样:
Len: 221
Len: 222
Len: 223
Len: 224
<a short pause about 1 second, then prints Len: 225 and continues>
Len: 226
Len: 227
...
..
.
稍后会在另一个行计数时再次发生,并在几百条记录后再次发生。
更新 2:
下面是我的 InfrastructureInit() 方法的片段
func InfrastructureInit() (*Infrastructure, []interface{}) {
irf := new(Infrastructure)
var ptrs []interface{}
ptrs = append(ptrs,
&irf.Base.ID,
&irf.Base.CreatedAt,
&irf.Base.UpdatedAt,
&irf.ListingID,
&irf.AddressID,
&irf.Type,
&irf.Name,
&irf.Description,
&irf.Details,
&irf.TravellingFor,
)
return irf, ptrs
}
我不确定是什么导致了这种缓慢,但我目前在我的服务器上放置了一个快速补丁,以使用 redis 数据库并预缓存我的基础设施,将其保存为字符串。现在似乎没问题,但我现在必须同时维护 redis 和我的 postgres。
我仍然对这种奇怪的行为感到困惑,但我并不完全了解 rows.Next() 的工作方式 - 每次我调用 rows.Next() 时它都会查询数据库吗?