在 MongoDB 中优化查询性能

Optimize query performance in MongoDB

我有一个名为 App 的集合,需要查询那些属于特定用户 (user_id) 或可供所有用户使用的活动 (active: true) 应用程序(通过他们 _id)。我使用这样的查询

{
    "active" : true,
    "$or" : [
        {
            "user_id" : "111111111111111111111111"
        },
        {
            "_id" : {
                "$in" : [
                    ObjectId("222222222222222222222222"),
                    ObjectId("333333333333333333333333"),
                    ObjectId("444444444444444444444444")
                ]
            }
        }
    ]
}

但是在 db.currentOp(true) 中,我看到这个查询 运行 非常慢:lockStats.timeLockedMicros.r 大约是 3000。 如何优化此查询的性能?我已经在 App 上有以下索引:

> db.App.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "mydb.App"
    },
    {
        "v" : 1,
        "key" : {
            "active" : 1,
            "created_at" : -1
        },
        "name" : "active_1_created_at_-1",
        "ns" : "mydb.App",
        "background" : true
    },
    {
        "v" : 1,
        "key" : {
            "active" : 1,
            "user_id" : 1
        },
        "name" : "active_1_user_id_1",
        "ns" : "mydb.App",
        "background" : true
    }
]

我在这里看到两个问题:

1) 您不需要在布尔字段 active 上建立索引,因为它的选择性较低并且不利于查询性能。

"If overall selectivity is low, and if MongoDB must read a number of documents to return results, then some queries may perform faster without indexes." source

2) 您需要为 user_id 创建索引,因为 user_id 无法使用您为 active_1_user_id_1

创建的复合索引

编辑:您始终可以通过执行 explain(true) 检查索引效率并查看该查询使用了哪些索引。

我会尝试做以下事情:

  • 删除所有索引,您的 active 字段基数较低(布尔值),对您根本没有帮助,您没有使用 created_at,所以没有理由这样做。
  • 仅在 user_id 键上添加索引
  • 将您的字符串从数字更改为数字。