Mongo优化:查询性能与数据库结构



上下文:连接到MongoDB 4.0服务器的NodeJs(meteorjs(应用程序

我有一组经常计算的数据,我需要存储 oevr 时间,然后从我的应用程序访问一组特定的数据。该集合是一个包含 12,000 个对象的数组,最终权重约为 3MB(通过在只有一组数据的集合上使用 MongoDB 集合统计信息来测量:大小:3,3MB;计数:12964(。它与一些计算参数有关。我需要使用查询检索集合。

我必须在两种数据库结构之间进行选择:

选项 1:一个集合存储带有 ID 的计算引用(我们将其命名为ReferenceCollection(,另一个集合将每个计算的所有 12000 个对象存储为单个文档,并且 referenceId 指向之前创建的 ID。

下面是一个示意图:

ReferenceCollection :
|--- _id: ObjectId("a")
|--- computation : "my reference"
ResultCollection : 
|--- _id: ObjectId("b")
|--- referenceId : ObjectId("a")
|--- fieldResut1 : data
.
.
|--- fieldResut20 : data

为了检索集合,我将使用计算参数查询第一个集合中的 referenceId(,然后使用引用 ID 查询第二个集合以获取 12 000 个文档。

let reference = ReferenceCollection.findOne({computation: "my reference"}) // this is lightweight
let results = ResultCollection.find({referenceId: reference._id}) // this search for the 12 000 results

选项 2:存储计算引用的单个集合,其键包含包含包含数据的数组

下面是一个示意图:

ResultCollection : 
|--- _id: ObjectId("b")
|--- computation : "my reference"
|--- result : Array(    
|--- fieldResut1 : data
.
.
|--- fieldResut20 : data
)

为了检索集合,我只需要使用我的计算参数执行一个查询,以获得包含我所有数据的单个文档。

问题:我在使用第一个选项时遇到性能问题:从MongoDB桌面客户端(studio 3T(查询和检索所有12000个文档非常慢:在我的设置中需要3秒。第二个选项只需 1 秒即可检索(这些时间包括数据下载(。它导致我的应用程序在获取数据时等待很长时间。

返回游标时,从服务器上的 mongoshell 查询非常快(选项 1 约为 20 毫秒(。


您能否确认选项 2 是存储此数据的不错选择?

关于数据结构,我还有其他选择吗?

我在单个节点上运行MongoDB。您认为设置副本集有助于提高读取性能吗?

在这种情况下,您可能会发现差异主要是由于必须执行两个主要与您的网络相关的连接/查询。

例如,如果事务集合中引用的用户集合,您将使用选项 1。

这个想法是,如果您需要连接两个集合,则只有在连接集合将被多次引用并且具有复杂文档时才这样做。

如果只是拥有一个名称集合,然后在另一个集合中引用,那就错了。

如果需要连接两个 Mongo 集合,请考虑使用聚合,以便 Mongo 服务器可以在一次命中中获取数据,而不是需要执行多个查询。

编辑:

为了让您了解性能,现在的第一个选项需要两倍的时间,纯粹是因为它必须连接两次。如果相同的查询经常发生,那么您真的会看到没有收益的性能下降(除非"计算"字段发生很大变化,否则这可能是合理的(。如果您使用的是聚合,那么您不会真正看到任何性能损失,因为它被视为单个连接。

选项二只是一次查找,然后是返回数组数据所需的时间。因此,在大多数情况下,使用聚合时与选项 1 相同。

还要考虑如果数组由复杂对象组成,则数组可能是一个瓶颈。理想情况下,您将避免使用数组并将其平展为带有字段的单个文档。这样,当您执行查询时,您可以设置要返回的字段,从而不返回不需要的字段。

最新更新