【问题标题】:MongoDB performance issue: Single Huge collection vs Multiple Small CollectionsMongoDB 性能问题:单个大集合与多个小集合
【发布时间】:2012-07-15 22:03:11
【问题描述】:

我测试了两个场景单个巨大集合与多个小型集合,发现查询时性能存在巨大差异。这就是我所做的。

案例 1:我创建了一个产品集合,其中包含 10 种不同类型产品的 1000 万条记录,其中每种产品类型恰好有 100 万条记录,并且我在 ProductType 上创建了索引。当我运行条件 ProductType=1 和 ProductPrice>100 和 limit(10) 的示例查询以返回 ProductType=1 且价格大于 100 的 10 条记录时,当集合中有很多价格的产品时,大约需要 35 毫秒大于 100,当 ProductType=1 中价格大于 100 的产品数量非常少时,相同的查询大约需要 8000 毫秒(8 秒)。

案例 2:我为每个 ProductType 创建了 10 个不同的 Product 表,每个 ProductType 包含 100 万条记录。在包含 productType 1 记录的集合 1 中,当我使用条件 ProductPrice>100 和 limit(10) 运行相同的示例查询以返回 10 条价格大于 100 的产品记录时,当集合有很多时大约需要 2.5 毫秒价格大于 100 的产品,当价格大于 100 的产品数量非常少时,相同的查询大约需要 1500 毫秒(1.5 秒)。

那么为什么会有这么大的差异呢?案例一和案例二之间的唯一区别是一个巨大的集合与多个较小的集合,但我在第一个案例中创建了 ProductType 的索引一个单一的巨大集合。我猜性能差异是由第一种情况下的索引引起的,我需要在第一种情况下使用该索引,否则性能会更差。由于索引,我预计第一种情况下的性能会有所下降,但我没想到第一种情况下的巨大差异会慢 10 倍。

所以 8000 毫秒与 1500 毫秒在一个大集合与多个小集合上。为什么?

【问题讨论】:

    标签: mongodb mongodb-.net-driver


    【解决方案1】:

    分离集合为您提供了一个免费的索引,而没有任何实际开销。索引扫描有开销,特别是如果索引并没有真正帮助您减少它必须扫描的结果数量(如果索引中有一百万个结果,但您必须全部扫描并检查它们,对你帮助不大)。

    简而言之,将它们分开是一种有效的优化,但是在您真正决定采用该方法之前,您应该为您的查询提供更好的索引,我认为这是一个激进的措施(产品价格的索引可能会帮助您更多本例)。

    使用 explain() 可以帮助您了解查询的工作原理。一些基础知识是: 理想情况下,您需要较低的 nscanned 与 n 比率。通常,您不需要 scanAndOrder = true,也不需要 BasicCursor(这意味着您根本没有使用索引)。

    【讨论】:

    • Case 1: // 这里查询的是一个大集合,ProductType=1 的所有记录都匹配 db.AllTogather.find({ProductType:10003, "Data.D_3" :/ksdhfkjsda/}).explain() {“光标”:“BtreeCursor ProductType_1”,“isMultiKey”:假,“n”:1000000,“nscannedObjects”:1000101,“nscanned”:1000101,“scanAndOrder”:假, “indexOnly”:假,“nYields”:4,“nChunkSkips”:0,“millis”:4016,“indexBounds”:{“ProductType”:[[10003,10003]]},“server”:“ANANDD:27017 " }
    • Case 2: // 这里我查询的是包含 ProductType=1 的所有记录并且所有记录都匹配的较小集合 >db.ProductType_10003.find({"Data.D_3" :/ksdhfkjsda/}).explain() { "cursor":"BasicCursor", "isMultiKey":false, "n":1000000, "nscannedObjects":1000000, "nscanned":1000000, "scanAndOrder":false, " indexOnly":false, "nYields":2, "nChunkSkips":0, "millis":1876, "indexBounds":{ }, "server":"ANANDD:27017" }
    • 您真的需要像这样查询特定产品类型的所有结果吗?或者您是否想对它们进行排序并按某个值限制到前 100 名。
    • 不,我会限制和跳过。
    猜你喜欢
    • 2012-11-27
    • 1970-01-01
    • 2016-01-25
    • 2021-09-30
    • 2013-04-12
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多