【问题标题】:Is there a way to force mongodb to store certain index in ram?有没有办法强制 mongodb 在 ram 中存储某些索引?
【发布时间】:2012-03-28 16:40:01
【问题描述】:

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

【问题讨论】:

  • 您是否尝试过在您的查询中运行“解释”以了解为什么它很慢?
  • @gWaldo 添加了示例查询,但查看它我没有发现任何线索。
  • 我将更新与此信息相关的答案。

标签: mongodb caching indexing ram nosql


【解决方案1】:

没有。 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”页面:

了解解释的输出。需要查看三个主要领域 在检查解释命令的输出时:

  • cursor:cursor 的值可以是 BasicCursor 或 BtreeCursor。 其中第二个表示给定查询正在使用索引。
  • nscanned:扫描的文档数。
  • n:文档数 由查询返回。您希望 n 的值接近 nscanned 的值。您要避免的是进行集合扫描, 也就是说,访问集合中的每个文档的位置。这是 当 nscanned 等于 收藏。
  • 毫秒:完成请求所需的毫秒数 询问。此值对于比较索引策略很有用,索引 与非索引查询等相比。

【讨论】:

  • 如果您需要保留持久数据,Redis 不是解决方案(尽管它很棒)。我很好奇 - 是什么让您认为 RAM 没有被使用?如果您的查询命中索引(您可以对其进行测试),则它们必须进入 RAM。
  • 您可以在 RAMdisk 上创建索引,但我会避免这样做;你增加了复杂性。
  • 这两篇文章并没有完全解决我认为您要问的问题,但它们可能会让您对 MongoDB 和 RAM 之间的关系有所了解。 blog.serverdensity.com/2011/01/31/mongodb-monitoring-mongostatarchitects.dzone.com/articles/some-useful-tips-mongodb
  • 我添加了几个(希望)相关且有用的链接
  • 更新了!分析和进一步的链接
【解决方案2】:

有没有办法强制 mongo 将此特定索引存储在 ram 中?

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

这将提供的唯一好处是,如果需要索引的这些部分,则可以使一些潜在的未来查询更快。

但是,如果已经运行的查询未访问索引的某些部分,为什么要更改此设置?

【讨论】:

  • 问题是我在某种“标签”上使用了多键索引,以便用户稍后在该字段上进行搜索。有些查询需要长达 100 秒,这太长了,我认为这是因为硬盘性能不佳,因为 ssd 和 hdd 机器之间存在巨大差异。
猜你喜欢
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 2016-07-06
  • 2010-10-09
相关资源
最近更新 更多