是否有任何工具可以估计 MongoDB 中的索引大小?

Posted

技术标签:

【中文标题】是否有任何工具可以估计 MongoDB 中的索引大小?【英文标题】:Are there any tools to estimate index size in MongoDB? 【发布时间】:2012-01-26 07:35:57 【问题描述】:

我正在寻找一种工具,可以根据以下几个信号来准确估计 MongoDB 索引的大小:

我的收藏中有多少文档 索引字段的大小 如果不是 ObjectId,我使用的 _id 的大小 地理/非地理

有没有人偶然发现过这样的事情?我可以想象它会非常有用,因为一旦 Mongo 遇到内存墙并且文档开始被分页到磁盘,它的性能就会下降。如果我有一个正常运行的数据库并且想要添加另一个索引,那么我知道它是否太大的唯一方法就是实际添加它。

它不需要精确到一点点,但是对于 B-Trees 和索引实现的一些假设,我相信它可能足够合理以提供帮助。

如果这还不存在,我想构建并开源它,所以如果我错过了这个计算所需的任何参数,请在你的答案中包括。

【问题讨论】:

将您的工具(以填补过渡时期的空白)与 MongoDB 团队对内置工具的请求相一致可能是值得的。 你真的为此编写了一个工具吗? 我做了,但是结果不太令人满意。当使用具有现有索引的真实数据进行测试以进行比较时,我的工具会预测索引大小略小于实际大小的两倍。我正在调查这是否是我的代码中的错误,或者公式是否只是非常粗糙。当我发现更多信息时会在这里更新。 @Stennie 我可能会撤回一个旧线程。但是有没有官方的综合方法来识别这一点? @Naman Tyler 2011 年的回答描述了大约 MongoDB 2.0 的原始 MMAP 存储引擎,但这个公式绝对不适用于现代版本的 MongoDB。 WiredTiger 是 MongoDB 3.2+ 中的默认存储引擎,使用索引前缀压缩,因此索引大小将根据键值的分布而变化。还有多种索引类型和选项可能会影响大小。进行合理估计的最佳方法是使用经验估计和具有代表性的测试数据来预测您的预期增长,因此我会将您对 Ostati 2014 年的回答投赞成票。 【参考方案1】:

我刚刚与一些 10gen 工程师交谈,没有工具,但您可以根据以下公式进行粗略计算:

2 * [ n * ( 18 bytes overhead + avg size of indexed field + 5 or so bytes of conversion fudge factor ) ]

n 是您拥有的文档数量。

开销和转换填充是特定于 mongo 的,但 2x 来自 b-tree 数据结构,在最坏的情况下大约是半满(但分配了 100% 的完整树所需的空间)。

我会解释更多,但我现在正在自己学习。本次演讲会有更多细节:http://www.10gen.com/presentations/mongosp-2011/mongodb-internals

【讨论】:

然后他可以创建一个在线计算器:-) 对不起,需要重新打开这个问题。通过计算具有代表性的文档数量的平均字段大小,并将其代入列出的等式,我得到的索引大小大约是实际值的两倍。这个理论在这里对我来说是有意义的,但在实践中,无论如何,基于 mongo shell 报告的内容,这是不正确的。 多少个文档,样本够大吗?请举个例子。实际大小显然会因许多不同的因素而有所不同。 我突然想到,我们可能会为 4k 索引桶中的最大索引字段大小分配空间,即使您在实践中使用了大约一半,所以实际索引大小大约是两倍。 嘿@TylerBrock,你能告诉我avg size of indexed field 是什么意思吗?如果我的文档看起来像 _id : 1, favoriteFood : "cheese" 并且我在 favoriteFood 上编制索引,那么“索引字段的平均大小”是否会是 12,因为它有 12 个字符?【参考方案2】:

您可以使用以下命令检查集合中索引的大小:

db.collection.stats()

更多详情:http://docs.mongodb.org/manual/reference/method/db.collection.stats/#db.collection.stats

【讨论】:

【参考方案3】:

另一种计算方法是将大约 1000 个文档提取到每个集合中,换句话说,为您将在生产中结束的内容构建一个小规模模型,创建索引或您拥有的内容并计算最终结果基于db.collection.stats() 平均值的数字。

编辑(来自a comment):

Tyler's answer 描述了大约 MongoDB 2.0 的原始 MMAP 存储引擎,但这 公式绝对不适用于现代版本的 MongoDB。 WiredTiger,MongoDB 3.2+ 中的默认存储引擎,使用索引 前缀压缩,因此索引大小将根据分布而有所不同 的关键值。还有多种索引类型和选项 这可能会影响大小。合理估计的最佳方法 将使用具有代表性测试数据的经验估计 您的预计增长。

【讨论】:

【参考方案4】:

最好的选择是在非产品部署中进行测试!

插入 1000 个文档并检查索引大小,插入 100000 个文档并检查索引大小等等。

在循环中检查所有集合总索引大小的简单方法:

  var y=0;db.adminCommand("listDatabases").databases.forEach(function(d)mdb=db.getSiblingDB(d.name);mdb.getCollectionNames().forEach(function(c)s=mdb[c].stats(1024*1024).totalIndexSize;y=y+s;print("db.Collection:"+d.name+"."+c+" totalIndexSize: "+s+" MB"); ));print("============================");print("Instance totalIndexSize: "+y+" MB");

【讨论】:

无疑是一种蛮力的做法,但当我推测在包含数百万个文档的现有数据库上添加一个或多个索引时,它是不可扩展的。顺便说一句,一旦我在 staging 上设置了相同的文档,我也可以执行 stats 来提取正确的信息。 另外,如果有非常密集的更新和删除为文档和索引分配的空间可能会有很大差异......

以上是关于是否有任何工具可以估计 MongoDB 中的索引大小?的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何有效的方法可以以最新的一阶对给定的 mongodb 数据进行分页并避免排序超出大数据的内存限制?

使用 2dsphere 索引和 IP 地址索引索引 mongodb 集合

详解Java工程师偏爱的大数据工具:MongoDB篇

详解Java工程师偏爱的大数据工具:MongoDB篇

是否有任何开源库可以将 sql 查询语言转换为相应的 mongodb 查询?

mongo之 前后台创建索引 --noIndexBuildRetry