有没有办法强制mongodb在ram中存储某些索引?

时间:2012-03-28 16:40:02

标签: mongodb caching indexing ram nosql

我有一个具有相对较大索引的集合(但可用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"
                        ]
                ]
        }
}

2 个答案:

答案 0 :(得分:5)

没有。 MongoDB允许系统管理存储在RAM中的内容。

话虽如此,你应该能够通过对索引运行查询(定期查看query hinting)来保持索引在RAM中。

有用的参考资料:

此外,Kristina Chodorow提供了此excellent answer regarding the relationship between MongoDB Indexes and RAM


<强>更新

在提供.explain()输出的更新之后,我看到以下内容:

  • 查询正在点击索引。
  • nscanned是检查的项目数(文档或索引条目)。
  • nscannedObjects是扫描的文档数
  • n是符合指定条件的文档数
  • 您的数据集是300393个条目,即索引中的项目总数以及匹配结果。

我可能读错了,但我读到的是你收藏的所有物品都是有效的结果。在不知道您的数据的情况下,似乎每个项目都包含标签“avi”。另一件事就是这个指数几乎没用;当索引尽可能地缩小结果字段时,索引提供最大的值。

来自MongoDB的“Indexing Advice and FAQ”页面:

  

了解解释的输出。有三个主要领域   用于检查explain命令的输出时:

     
      
  • cursor:cursor的值可以是BasicCursor或BtreeCursor。   第二个指示给定查询使用索引。
  •   
  • nscanned:扫描的文件数量。
  •   
  • n:文件数量   由查询返回。您希望n的值接近   nscanned的值。您要避免的是进行收集扫描,   也就是说,访问集合中的每个文档。这是   nscanned等于文件数量的情况   集合。
  •   
  • millis:完成此操作所需的毫秒数   查询。此值对于比较索引的索引策略非常有用   与非索引查询等。
  •   

答案 1 :(得分:2)

  

有没有办法强制mongo在ram中存储这个特定的索引?

当然,您可以使用仅索引查询来遍历索引。这将迫使MongoDB加载索引的每个块。但它必须是“仅索引”,否则您还将加载所有相关文档。

这将带来的唯一好处是,如果需要索引的那些部分,可以更快地进行一些潜在的未来查询。

但是,如果已经运行的查询没有访问索引的某些部分,为什么要更改它?