我在一个集合中有大约1000000个文档(随机生成)。
示例文档:
{
"loc": {
"lat": 39.828475,
"lon": 116.273542
},
"phone": "",
"keywords": [
"big",
"small",
"biggest",
"smallest"
],
"prices": [
{
"category": "uRgpiamOVTEQ",
"list": [
{
"price": 29,
"name": "ehLYoPpntlil"
}
]
},
{
"category": "ozQNmdwpwhXPnabZ",
"list": [
{
"price": 96,
"name": "ITTaLHf"
},
{
"price": 88,
"name": "MXVgJFBgtwLYk"
}
]
},
{
"category": "EDkfKGZSou",
"list": [
{
"price": 86,
"name": "JluoCLnenOqDllaEX"
},
{
"price": 35,
"name": "HbmgMDfxCOk"
},
{
"price": 164,
"name": "BlrUD"
},
{
"price": 106,
"name": "LOUcsMDeaqVm"
},
{
"price": 14,
"name": "rDkwhN"
}
]
}
],
}
无索引搜索
> db.test1.find({"prices.list.price": { $gt: 190 } }).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 541098,
"nscannedObjects" : 1005584,
"nscanned" : 1005584,
"nscannedObjectsAllPlans" : 1005584,
"nscannedAllPlans" : 1005584,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 8115,
"nChunkSkips" : 0,
**"millis" : 13803,**
"server" : "localhost:27017",
"filterSet" : false
}
带索引:
> db.test1.ensureIndex({"prices.list.price":1,"menu.list.name":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.test1.find({"prices.list.price": { $gt: 190 } }).explain()
{
"cursor" : "BtreeCursor prices.list.price_1_prices.list.name_1",
"isMultiKey" : true,
"n" : 541098,
"nscannedObjects" : 541098,
"nscanned" : 868547,
"nscannedObjectsAllPlans" : 541098,
"nscannedAllPlans" : 868547,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 16852,
"nChunkSkips" : 0,
**"millis" : 66227,**
"indexBounds" : {
"menu.list.price" : [
[
190,
Infinity
]
],
"menu.list.name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost:27017",
"filterSet" : false
}
知道为什么索引搜索比没有索引搜索慢吗?
此外,我将使用:
db.test1.find({loc:{$near:[39.876045,32.862245]})(需要2d索引)
db.test1.find({keywords:{$in:[“small”,“another”]})(对关键字使用索引)
db.test1.find({“prices.list.name”:/.s./})(不需要索引,因为我将使用regex)
最佳答案
索引允许更快地访问满足查询的文档位置。
在您的示例中,查询选择集合中所有文档的一半。因此,尽管索引扫描提供了更快的访问来知道哪些文档将匹配查询谓词,但它实际上创建了更多的总体工作。
在集合扫描中,查询将扫描所有文档,并检查要查询的字段以查看是否匹配。有一半的时间最终选择了文档。
在索引扫描中,查询遍历所有索引项的一半,然后从它们直接跳到满足查询谓词的文档。在你的案子里还有更多的行动。
此外,在执行此操作时,当需要等待必须读取的文档被带到ram中时,或者当存在等待进行的写入时,操作将生成读取互斥量,并且索引扫描显示的结果数是集合扫描的两倍。如果您没有足够的内存用于工作集,那么添加索引将给现有资源带来更大的压力,并使事情变得更慢,而不是更快。
使用price与更大的数字(比如500)进行比较(或者在您的数据集中更具选择性)。如果使用索引查询仍然比较慢,那么您可能会在系统上看到许多页面错误。但是,如果有足够的内存用于索引,那么索引查询将快得多,而未索引查询将同样慢。
关于mongodb - Mongodb - 指数较慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24714967/