我有一组具有以下架构的 CIDR 范围:
{ bottom: Number
top: Number
cidrText: String
live: Boolean
hits: Number }
我想要做的是找出一个 ip 是否在底部 + 顶部范围内(然后对该记录上的命中执行 $inc 更新。
目前我的指数是:
db.tbl.ensureIndex( { bottom: 1, top: 1, live: 1 } );
但是当我运行我的查询时 - 只有部分查询使用索引,然后这对我的服务器性能有很大影响:
我的查询是:
db.tbl.find({ live: true, top: { $gte: 3266341261 }, bottom: { $lte: 3266341261 } })
解释输出是:
{
"cursor" : "BtreeCursor top_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 7,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"top" : [
[
3266341261,
1.7976931348623157e+308
]
]
},
"server" : "local:27017"
}
有没有办法让 $gte 和 $lte 都使用相同的索引 - 或者我应该运行 2 个查询并在两个查询中找到匹配的行?
编辑 我已经删除了所有现有索引并重新添加了复合索引,现在我得到了正确的界限,但 nscanned 仍然很高。
{
"cursor" : "BtreeCursor bottom_1_top_1_live_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 4748,
"nscannedObjectsAllPlans" : 4746,
"nscannedAllPlans" : 9494,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 15,
"indexBounds" : {
"bottom" : [
[
-1.7976931348623157e+308,
3633904421
]
],
"top" : [
[
3633904421,
1.7976931348623157e+308
]
],
"live" : [
[
true,
true
]
]
},
"server" : "local27017"
}
我也在我的日志中得到这个:
warning: ClientCursor::yield can't unlock b/c of recursive lock ns: col.tbl top: { opid: 25701683, active: true, secs_running: 0, op: "query", ns: "tbl", query: { findandmodify: "tbl", query: { live: true, top: { $gte: 1584813140 }, bottom: { $lte: 1584813140 } }, sort: {}, new: 1, remove: 0, upsert: 0, update: { $inc: { hits: 1 } } }, client: "127.0.0.1:39407", desc: "conn581", threadId: "0x497ec940", connectionId: 581, locks: { ^: "w", ^tbl: "W" }, waitingForLock: false, numYields: 0, lockStats: { timeLockedMicros: {}, timeAcquiringMicros: { r: 0, w: 3 } } }
编辑 2
太清楚“查找参数的顺序”看起来确实像搜索词的顺序确实需要匹配索引顺序(至少在 2.4.4 中)。运行这 2 个查询 - 一个使用完整索引,另一个不使用。
> db.tbl.find({top: {$lte: 1454442030}, bottom: {$gte: 1454442030}}).explain()
{
"cursor" : "BtreeCursor top_1",
"isMultiKey" : false,
"n" : 2,
"nscannedObjects" : 2271,
"nscanned" : 2271,
"nscannedObjectsAllPlans" : 6816,
"nscannedAllPlans" : 11396,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 24,
"indexBounds" : {
"top" : [
[
-1.7976931348623157e+308,
1454442030
]
]
},
"server" : "local:27017"
}
和
> db.tbl.find({bottom: {$lte: 1454442030}, top: {$gte: 1454442030}}).explain()
{
"cursor" : "BtreeCursor bottom_1_top_1_live_1",
"isMultiKey" : false,
"n" : 2,
"nscannedObjects" : 2,
"nscanned" : 2080,
"nscannedObjectsAllPlans" : 6240,
"nscannedAllPlans" : 10400,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 23,
"indexBounds" : {
"bottom" : [
[
-1.7976931348623157e+308,
1454442030
]
],
"top" : [
[
1454442030,
1.7976931348623157e+308
]
],
"live" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "local:27017"
}
谢谢
标记