我遇到了mongodb查询的问题,即使在创建适当的索引以对结果文档进行排序后,扫描也仍然很高。 下面是查询
db.ratebus.find({
$and: [{
_id.trg: {
$in: [54875973]
}
}, {
rating: {
$gte: 3
}
}]
}).sort({
revType: -1,
updated_at: -1
}).hint({
_id.trg: 1,
rating: -1,
revType: -1,
updated_at: -1
}).limit(10)
下面是事件探查器的输出
2018-10-08T13:03:15.986+0530 I COMMAND [conn1370938] command jdsocial.ratebus command: find {
find: "ratebus",
filter: {
$and: [{
_id.trg: {
$in: [54875973]
}
}, {
rating: {
$gte: 3
}
}]
},
sort: {
revType: -1,
updated_at: -1
},
hint: {
_id.trg: 1,
rating: -1,
revType: -1,
updated_at: -1
},
limit: 10
}
planSummary: IXSCAN {
_id.trg: 1.0, rating: -1.0, revType: -1.0, updated_at: -1.0
}
keysExamined: 37423 docsExamined: 37423 hasSortStage: 1 cursorExhausted: 1 keyUpdates: 0 writeConflicts: 0 numYields: 292 nreturned: 10 reslen: 4047 locks: {
Global: {
acquireCount: {
r: 586
},
acquireWaitCount: {
r: 26
},
timeAcquiringMicros: {
r: 179979
}
},
Database: {
acquireCount: {
r: 293
}
},
Collection: {
acquireCount: {
r: 293
}
}
} protocol:op_query 692ms
在此清晰可见,限制为10条记录正在扫描37423个文档。任何帮助将不胜感激。
在db中采样记录:
{
"_id" : {
"src" : 2584095,
"trg" : 54877444
},
"revid" : "0805639673",
"rating" : 2,
"age" : ISODate("2012-11-14T15:41:09Z"),
"updated_at" : ISODate("2012-11-14T15:41:09Z"),
"hasrev" : 0,
"revType" : 0,
"has_rev" : false,
"rev" : ""
},
{
"_id" : {
"src" : 38266391,
"trg" : 54878562
},
"revid" : "0805639674",
"rating" : 4,
"age" : ISODate("2012-11-14T15:41:14Z"),
"updated_at" : ISODate("2012-11-14T15:41:14Z"),
"hasrev" : 0,
"revType" : 0,
"has_rev" : false,
"rev" : "",
"comment_id" : NumberLong("1531272078171327")
}
创建的索引:
{
"v" : 1,
"key" : {
"_id.trg" : 1,
"rating" : -1,
"revType" : -1,
"updated_at" : -1
},
"name" : "_id.trg_1_rating_-1_revType_-1_updated_at_-1",
"ns" : "jdsocial.ratebus"
}
答案 0 :(得分:3)
要完成@Alex Blex的答案,我想说排序部分应该在索引前缀中,因为您在查询中使用了$ in。
让我解释一下:MongoDB使用索引的策略如下:1)相等-2)排序-3)范围。正如您在查询的过滤器部分中使用$ in一样,此查询位于策略的“范围”部分。因此,优先级被赋予了排序阶段,它不能正确使用索引,因为它与索引前缀不匹配。
为您提供了两种解决方案:如Alex所述创建新索引,或将_id.trg: {$in: [54875973]}
替换为_id.trg: {$eq: [54875973]}
。唯一要选择的问题是“我是否真的需要此查询的ID范围?”
答案 1 :(得分:1)
排序部分应位于index prefix中。您拥有的索引
{
"_id.trg" : 1,
"rating" : -1,
"revType" : -1,
"updated_at" : -1
}
不支持
排序{
revType: -1,
updated_at: -1
}
应该具有正确顺序的索引字段:
{
"revType" : -1,
"updated_at" : -1,
"_id.trg" : 1,
"rating" : -1
}