我有一个具有相对较大索引的集合(但可用ram少)并且查看此集合上的find性能以及我的系统中由htop给出的免费ram数量似乎mongo没有存储完整索引内存。有没有办法强制mongo在ram中存储这个特定的索引?
示例查询:
> db.barrels.find({"tags":{"$all": ["avi"]}}).explain()
{
"cursor" : "BtreeCursor tags_1",
"nscanned" : 300393,
"nscannedObjects" : 300393,
"n" : 300393,
"millis" : 55299,
"indexBounds" : {
"tags" : [
[
"avi",
"avi"
]
]
}
}
并非所有对象都标有“avi”标签:
> db.barrels.find().explain()
{
"cursor" : "BasicCursor",
"nscanned" : 823299,
"nscannedObjects" : 823299,
"n" : 823299,
"millis" : 46270,
"indexBounds" : {
}
}
没有“$ all”:
db.barrels.find({"tags": ["avi"]}).explain()
{
"cursor" : "BtreeCursor tags_1 multi",
"nscanned" : 300393,
"nscannedObjects" : 300393,
"n" : 0,
"millis" : 43440,
"indexBounds" : {
"tags" : [
[
"avi",
"avi"
],
[
[
"avi"
],
[
"avi"
]
]
]
}
}
当我搜索两个或更多标签时,它会发生这种情况(它会扫描每个项目,好像没有索引):
> db.barrels.find({"tags":{"$all": ["avi","mp3"]}}).explain()
{
"cursor" : "BtreeCursor tags_1",
"nscanned" : 300393,
"nscannedObjects" : 300393,
"n" : 6427,
"millis" : 53774,
"indexBounds" : {
"tags" : [
[
"avi",
"avi"
]
]
}
}
答案 0 :(得分:5)
没有。 MongoDB允许系统管理存储在RAM中的内容。
话虽如此,你应该能够通过对索引运行查询(定期查看query hinting)来保持索引在RAM中。
有用的参考资料:
此外,Kristina Chodorow提供了此excellent answer regarding the relationship between MongoDB Indexes and RAM
<强>更新强>
在提供.explain()输出的更新之后,我看到以下内容:
我可能读错了,但我读到的是你收藏的所有物品都是有效的结果。在不知道您的数据的情况下,似乎每个项目都包含标签“avi”。另一件事就是这个指数几乎没用;当索引尽可能地缩小结果字段时,索引提供最大的值。
来自MongoDB的“Indexing Advice and FAQ”页面:
了解解释的输出。有三个主要领域 用于检查explain命令的输出时:
- cursor:cursor的值可以是BasicCursor或BtreeCursor。 第二个指示给定查询使用索引。
- nscanned:扫描的文件数量。
- n:文件数量 由查询返回。您希望n的值接近 nscanned的值。您要避免的是进行收集扫描, 也就是说,访问集合中的每个文档。这是 nscanned等于文件数量的情况 集合。
- millis:完成此操作所需的毫秒数 查询。此值对于比较索引的索引策略非常有用 与非索引查询等。
答案 1 :(得分:2)
有没有办法强制mongo在ram中存储这个特定的索引?
当然,您可以使用仅索引查询来遍历索引。这将迫使MongoDB加载索引的每个块。但它必须是“仅索引”,否则您还将加载所有相关文档。
这将带来的唯一好处是,如果需要索引的那些部分,可以更快地进行一些潜在的未来查询。
但是,如果已经运行的查询没有访问索引的某些部分,为什么要更改它?