我的数据层使用了相当数量的Mongo聚合,平均而言,返回查询需要花费500-650 My。我正在使用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 my?
我知道我可能会因为使用聚合管道而受到一些性能的影响,但我不认为它会如此糟糕。
发布于 2016-12-06 17:01:48
。。有什么明显的东西可以说明为什么我的问话者平均有500到650毫秒?
是的,有。在执行每个查询之前都要调用mgo.Dial()。mgo.Dial()每次都必须连接到MongoDB服务器,在查询后立即关闭该服务器。连接很可能需要数百毫秒才能建立起来,包括身份验证、分配资源(包括服务器端和客户端)等等。这是非常浪费的。
这个方法通常只对给定的集群调用一次,然后使用获得的会话上的New或Copy方法来建立到同一个集群的进一步的会话。这将使它们共享基础集群,并适当地管理连接池。
创建一个全局会话变量,在启动时连接一次(例如使用包init()函数),并使用该会话(或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...
}https://stackoverflow.com/questions/40999637
复制相似问题