我们想要查询整个实时制作的MongoDB集合(v2.6,大约70M文档的大约500GB数据)。
我们想知道最好的方法是什么:
我们不确定什么是最佳做法,并且会产生最佳效果,而对性能的影响最小。
答案 0 :(得分:1)
我会选择1.& 2.尽可能混合:在页面中迭代您的巨大数据集,但通过查询而不是跳过它们来访问这些页面,因为docs也指出这可能代价高昂。
cursor.skip()方法通常很昂贵,因为它需要 服务器从集合或索引的开头走到get 开始返回结果之前的偏移或跳过位置。作为 offset(例如上面的pageNumber)增加,cursor.skip()将成为 更慢,更密集的CPU。使用更大的集合,cursor.skip() 可能会成为IO界限。
因此,如果可能的话,在索引字段上构建页面并使用相应的查询范围处理这些批量数据。
答案 1 :(得分:1)
一般来说,大多数驱动程序无论如何都会加载批量文档。所以你的语言相当于
var docs = db.yourcoll.find()
docs.forEach(
function(doc){
//whatever
}
)
实际上最初只是创建一个游标,然后,当当前批次接近耗尽时,将透明地加载一个新批次。因此,在计划访问集合中的每个文档时手动执行此分页几乎没有任何优势,但保留了多个查询的开销。
对于ETL,手动迭代文档进行修改然后将它们存储在新实例中在大多数情况下对我来说似乎不合理,因为你基本上重新发明了轮子。
一般来说,没有一种适合所有“最佳”的方式。最好的方法是最适合您的功能和非功能需求。
从MongoDB到MongoDB进行ETL时,我通常按以下步骤进行:
除非你有非常复杂的转换,MongoDB's aggregation framework是一个令人惊讶的ETL工具。我为此目的定期使用它,并且尚未发现使用MongoDB ETL的聚合框架无法解决的问题。鉴于通常每个文档都是逐个处理的,如果可以注意到,对生产环境的影响应该是最小的。完成转换后,只需使用$out
stage将结果保存到新集合中。
使用$lookup
stage即可实现跨越转换的集合。
在对旧实例进行提取和转换后,为了将数据加载到新的MongoDB实例,您有以下几种可能性:
db.CloneCollection()
。这里的优点是您只需要转移所需的集合,但需要花费更多的手工工作。db.cloneDatabase()
复制整个数据库。除非原始实例上有多个数据库,否则此方法与副本集方法相比几乎没有优势。正如所写,在不知道您的确切用例,转换和约束的情况下,很难说哪种方法对您最有意义。
答案 2 :(得分:1)
MongoDB 3.4支持并行收集扫描。我自己从未尝试过这个。但看起来很有趣。
这不适用于分片群集。如果我们有并行处理设置,这肯定会加快扫描速度。
请参阅此处的文档:https://docs.mongodb.com/manual/reference/command/parallelCollectionScan/