Mongodb 未使用Mongo索引
我为正在执行的特定查询创建了一个围绕多个项的索引:Mongodb 未使用Mongo索引,mongodb,Mongodb,我为正在执行的特定查询创建了一个围绕多个项的索引: { "v" : 1, "key" : { "MODIFIED" : -1, "state" : 1, "fail" : 1, "generated" : 1 }, "ns" : "foo.bar", "name" : "MODIFIED_-1_state_1_fail_1_generated" } 然而,当我执行我的查询时,它不会使用我的索
{
"v" : 1,
"key" : {
"MODIFIED" : -1,
"state" : 1,
"fail" : 1,
"generated" : 1
},
"ns" : "foo.bar",
"name" : "MODIFIED_-1_state_1_fail_1_generated"
}
然而,当我执行我的查询时,它不会使用我的索引。你能提供一些我做错了什么的证据吗
谢谢大家!
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
"$or": [
{"state": "ca"},
{"state": "ok"}
]
}
],
"$and": [
{"fail": {"$ne": 1}},
{"generated": {"$exists": false}}
]
}).explain();
{
"cursor" : "BasicCursor",
"nscanned" : 464215,
"nscannedObjects" : 464215,
"n" : 0,
"millis" : 7549,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
有一个很好的理由,你的索引不能用于你的查询,我也认为查询本身存在一些问题。它没有命中索引的原因是嵌套的$or运算符,但我认为您实际的问题是对MongoDB中可用的所有运算符缺乏了解: 首先,您的嵌套$or检查状态是否为“ca”或“ok”是不必要的,并且(因为这是您没有命中索引的主要原因)可以替换为
state:{$in:[“ca”,“ok”]}
,这与此完全相同。现在您的查询是:
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"$and": [
{"fail": {"$ne": 1}},
{"generated": {"$exists": false}}
]
}).explain();
它会击中你的指数。第二个问题是不需要顶级的$and子句。请注意,和(或(A,B)和(C,D))=和(或(或(A,B),C,D)
。此查询执行相同的操作:
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"fail": {"$ne": 1},
"generated": {"$exists": false}
}).explain();
这仍然符合指数:
{
"clauses" : [
{
"cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"MODIFIED" : [
[
{
"$maxElement" : 1
},
{
"sec" : 1321419600,
"usec" : 0
}
]
],
"state" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"fail" : [
[
{
"$minElement" : 1
},
1
],
[
1,
{
"$maxElement" : 1
}
]
],
"generated" : [
[
null,
null
]
]
}
},
{
"cursor" : "BasicCursor",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
],
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1
}
希望有帮助!顺便说一句,复合索引中的第一个键的顺序是1,第二个键的顺序是-1,这稍微有点传统。请注意,-1仅用于确定相对于上一个字段的方向。感谢您的精彩回答;还有一点教育!调整好了,一切都很好;快得多。再次感谢您的帮助!