MongoDB性能问题:单个巨大集合 vs 多个小集合

13
我测试了单个巨大集合与多个小集合的两种情况,并在查询时发现性能上存在巨大差异。以下是我的操作:
场景1:我创建了一个产品集合,其中包含10种不同类型的产品,总共有1000万条记录,每种产品类型都有100万条记录,并在ProductType上创建了索引。当我运行一个样本查询来检索10个ProductType = 1且价格大于100的记录时,而限制结果只返回10个记录,这需要约35毫秒时间。但是,当ProductType = 1的记录很少并且价格大于100时,相同的查询需要大约8000毫秒(8秒)��能完成。
场景2:我为每种产品类型创建了10个不同的产品表格,每个表格包含100万条记录。在第一张表格中,即仅包含ProductType = 1的记录的表格中,我运行了同样的样本查询,要求返回价格大于100的10个记录,这需要大约2.5毫秒时间。但是,当ProductType = 1的记录很少并且价格大于100时,相同的查询需要约1500毫秒(1.5秒)才能完成。
那么,为什么会有这么大的差异呢?第一种和第二种场景之间唯一的区别就是一个巨大的集合和多个更小的集合。但是,在第一种情况下,我为单个巨大集合创建了ProductType的索引。我猜想第一种情况下的性能差异是由于索引造成的,并且我需要在第一种情况下使用这个索引,否则性能会更加糟糕。我预期第一种情况下由于索引而导致性能稍有下降,但我没有预料到第一种情况下会出现如此之大的性能下降,约慢了10倍。
所以是一个巨大集合 vs 多个小集合,运行时间分别为8000毫秒和1500毫秒。为什么呢?
1个回答

18

将集合分开可以提供一个没有真正负担的自由索引。有索引扫描的开销,尤其是如果索引不能帮助您削减它必须扫描(如果您有一百万个结果但必须全部扫描和检查,则不会对您有太多帮助)。

简而言之,将它们分离出来是一种有效的优化,但在实际决定采取这种方法之前,您应该为查询优化您的索引,我认为这是一项极端的措施(在本例中,商品价格上的索引可能更有帮助)。

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


案例1://在这里,我正在查询一个大集合,并且所有ProductType = 1的记录都有匹配项 db.AllTogather.find({ProductType:10003,“Data.D_3”:/ ksdhfkjsda /}).explain() { “cursor”:“BtreeCursor ProductType_1”, “isMultiKey”:false, “n”:1000000, “nscannedObjects”:1000101, “nscanned”:1000101, “scanAndOrder”:false, “indexOnly”:false, “nYields”:4, “nChunkSkips”:0, “millis”:4016, “indexBounds”:{ “ProductType”:[[10003,10003]] }, “server”:“ANANDD:27017” } - Anand Dayalan
情况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” }
- Anand Dayalan
你真的需要像那样查询特定产品类型的所有结果吗?或者你想按某个值进行排序并将其限制为前100个,或者其他什么操作。 - Eve Freeman
不,我进行了限制和跳过。 - Anand Dayalan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接