mongodb - mgo - 查询性能似乎一直很慢(500-650ms)

标签 mongodb performance go mgo

我的数据层大量使用 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/

相关文章:

mongodb - meteor ,Mongo 查询查找每第 n 个文档

java - 在 Spring MVC 中,在哪里启动和结束计数器来测试速度执行时间?

go - 使用上下文取消子进程的执行

interface - 在 go 中输入不可知的 channel

mongodb - 在 MongoDB 中建模用户到项目的数据库

mongodb - 连接后 mongobee 在 Atlas 集群上读取 DBname.system.indexes 失败

java - 存储一组静态字符串值的最佳方法

google-app-engine - 应用引擎/去 : Using a new version of Go with the SDK

mongodb - 从 fs.files 中投影一列

python - 加快 pandas 滚动窗口的速度