我的数据层大量使用 Mongo 聚合,平均而言,查询需要 500-650 毫秒才能返回。我正在使用 mgo
。
下面显示了一个示例查询函数,它代表了我的大多数查询的样子。
func (r userRepo) GetUserByID(id string) (User, error) {
info, err := db.Info()
if err != nil {
log.Fatal(err)
}
session, err := mgo.Dial(info.ConnectionString())
if err != nil {
log.Fatal(err)
}
defer session.Close()
var user User
c := session.DB(info.Db()).C("users")
o1 := bson.M{"$match": bson.M{"_id": id}}
o2 := bson.M{"$project": bson.M{
"first": "$first",
"last": "$last",
"email": "$email",
"fb_id": "$fb_id",
"groups": "$groups",
"fulfillments": "$fulfillments",
"denied_requests": "$denied_requests",
"invites": "$invites",
"requests": bson.M{
"$filter": bson.M{
"input": "$requests",
"as": "item",
"cond": bson.M{
"$eq": []interface{}{"$$item.active", true},
},
},
},
}}
pipeline := []bson.M{o1, o2}
err = c.Pipe(pipeline).One(&user)
if err != nil {
return user, err
}
return user, nil
}
我拥有的 user
结构如下所示..
type User struct {
ID string `json:"id" bson:"_id,omitempty"`
First string `json:"first" bson:"first"`
Last string `json:"last" bson:"last"`
Email string `json:"email" bson:"email"`
FacebookID string `json:"facebook_id" bson:"fb_id,omitempty"`
Groups []UserGroup `json:"groups" bson:"groups"`
Requests []Request `json:"requests" bson:"requests"`
Fulfillments []Fulfillment `json:"fulfillments" bson:"fulfillments"`
Invites []GroupInvite `json:"invites" bson:"invites"`
DeniedRequests []string `json:"denied_requests" bson:"denied_requests"`
}
根据我提供的信息,是否有任何明显的迹象表明我的查询平均为 500-650 毫秒?
我知道我可能会因使用聚合管道而承受一些性能损失,但我没想到会如此糟糕。
最佳答案
.. is there anything obvious that would suggest why my queriers are averaging 500-650ms?
是的,有。您调用mgo.Dial()
在执行每个查询之前。 mgo.Dial()
每次都必须连接到 MongoDB 服务器,您在查询后立即关闭该服务器。建立连接很可能需要数百毫秒,包括身份验证、分配资源(在服务器端和客户端)等。这是非常浪费的。
This method is generally called just once for a given cluster. Further sessions to the same cluster are then established using the New or Copy methods on the obtained session. This will make them share the underlying cluster, and manage the pool of connections appropriately.
创建一个全局 session 变量,在启动时连接一次(使用例如包 init()
函数),并使用该 session (或它的副本/克隆) ,由 Session.Copy()
或 Session.Clone()
获得)。
例如:
var session *mgo.Session
var info *db.Inf // Use your type here
func init() {
var err error
if info, err = db.Info(); err != nil {
log.Fatal(err)
}
if session, err = mgo.Dial(info.ConnectionString()); err != nil {
log.Fatal(err)
}
}
func (r userRepo) GetUserByID(id string) (User, error) {
sess := session.Clone()
defer sess.Close()
// Now we use sess to execute the query:
var user User
c := sess.DB(info.Db()).C("users")
// Rest of the method is unchanged...
}
关于mongodb - mgo - 查询性能似乎一直很慢(500-650ms),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40999637/