为什么在MongoDB中完全扫描表需要更长的时间?

时间:2012-08-20 11:39:26

标签: mongodb

我已经用10 M行数据进行了测试。每行有3个整数和2个字符串列。首先,我将此数据导入mongoDB,这是一个单独的分片。我在非索引列上使用db.table.find()进行简单的“where”查询。查询获取单行,大约需要7秒。

在同一硬件上,我将相同的数据加载到内存中的c#列表中。我做了一个while循环来扫描所有10M数据并做一个简单的相等控制来模拟查询的位置。它只需要大约650毫秒,比MongoDB快得多。

我有一台32 GB的机器,所以mongodb对内存映射表没有问题。

为什么mongoDB要慢得多?是因为mongoDB将数据保存在难以完全扫描的数据结构中,还是因为内存映射与将数据保存在变量中的方式不同。

2 个答案:

答案 0 :(得分:5)

正如Remon指出的那样,你肯定在这次测试中将苹果与橙子进行比较。

要进一步了解该表扫描中幕后发生的事情,请阅读MongoDB内部here。 (在存储模型下查看)

enter image description here 扩展区的概念代表连续的磁盘空间。

每个范围都指向一个链接的文档列表。

doc包含BSON格式的数据。所以现在你可以想象我们将如何检索数据。

现在,右上角恰如其分地显示了索引的美感。 MongoDB使用BTree结构进行导航,速度非常快。

尝试更改测试以进行一些热身运行并使用索引。

更新:我已经做了一些测试,作为我日常工作的一部分,将JBoss Cache(内存中的Java Cache)与MongoDB的性能作为应用程序缓存(针对_id的查询)进行比较。结果非常可比。

答案 1 :(得分:2)

从哪里开始......

首先,测试完全是苹果和橘子。将数据集加载到内存中并对其进行完全内存中扫描绝不等于任何数据库上的表扫描。

我也愿意打赌你正在对冷数据进行测试,并且MongoDB性能会随着热数据交换到内存而大幅提升。请注意,MongoDB不会抢先将数据交换到内存中。如果且仅当数据被频繁访问(或根本不需要)时,它才会这样做。实际上,操作系统更准确,因为MongoDB的存储引擎是建立在MMF(内存映射文件)之上的。

简而言之,您的测试不是一个好的测试,而您测试MongoDB的方式并不能产生准确的结果。您正在使用C#等效测试一个理论上最好的案例,除此之外,它比数据库代码复杂得多。