代码之家  ›  专栏  ›  技术社区  ›  Victor

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

  •  0
  • Victor  · 技术社区  · 6 年前

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

    一个集合,用于存储具有ID的计算引用(我们将其命名为 ReferenceCollection ),以及另一个集合,其中每个计算的所有12000个对象存储为单个文档,引用ID指向之前创建的ID。

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

    为了检索集合,我将使用计算参数查询第一个集合中的referenceId,然后使用referenceId查询第二个集合以获得12000个文档。

    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桌面客户端(studio3t)查询和检索所有12000个文档非常慢:在我的设置中只有3秒。第二个选项只需1秒即可检索(这些时间包括下载数据)。它会导致我的应用程序在获取数据时等待很长时间。


    您能确认选项2是存储此数据的好选择吗?

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

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   Casey Gibson    6 年前

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

    例如,在事务集合中引用的用户集合的情况下,将使用选项1。

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

    如果只是有一个名称集合,然后在另一个集合中引用,那么这是错误的。

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

    为了让您了解性能,目前的第一个选项需要两倍的时间,因为它必须连接两次。如果同一个查询经常发生,那么您将真正看到一个性能损失而没有任何收益(除非“computation”字段变化很大,否则这可能是合理的)。如果您使用的是聚合,那么就不会真正看到任何性能损失,因为它被认为是单个连接。

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