在 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
键上添加索引
- 将您的字符串从数字更改为数字。
我有一个名为 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
键上添加索引 - 将您的字符串从数字更改为数字。