我对集合大小和查询性能有疑问 -
有2个dbs-DB1& DB2。 DB1有1个集合,这里是此集合中stats()的输出 -
{
…
"count" : 2085217,
"size" : 17048734192,
"avgObjSize" : 8176,
"capped" : false,
"nindexes" : 3,
"indexDetails" : {},
"totalIndexSize" : 606299456,
"indexSizes" : {
"_id_" : 67664576,
"id_1" : 284165056,
"id_2" : 254469824
},
…
}
使用索引id_1对此集合进行的查询返回0.012秒。这是explain() -
的输出"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 0,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
….
"indexName" : "id_1",
}
在DB2中,我有4个集合,这里是DB2上的stats输出 -
{
…
"collections" : 4,
"objects" : 152655935,
"avgObjSize" : 8175.998307514215,
"dataSize" : 1248114666192,
"storageSize" : 1257144933456,
"indexes" : 12,
"indexSize" : 19757688272,
"fileSize" : 1283502112768,
…
}
使用我通过explain()确认的索引对DB2中的任何集合进行查询,至少比前一个查询对DB1的时间加倍。
由于mongo应该很好地扩展,为什么会出现这种差异?我读到mongodb加载了内存中的所有索引,并且由于DB2的容量大于DB1,这就是为什么它需要更长的时间?
任何见解都会非常有帮助。感谢。
编辑1: 添加更多信息。集合定义,索引定义和执行的查询...
所有集合(在两个DB中)都包含相同的字段;只有文件的数值和大小不同。
而且,这里是相关指数 -
"1" : {
"v" : 1,
"unique" : true,
"key" : {
"id" : 1
},
"name" : "id_1",
"ns" : "ns.coll1"
}
而且,这就是id字段的样子:
"_id" : ObjectId("55f9b6548aefbce6b2fa2fac"),
"id" : {
"pid" : {
"f1" : "val1",
"f2" : "val2"
}
},
而且,这是一个示例查询 -
db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}})
编辑2: 这里有关于硬盘和硬盘的更多信息。 RAM -
$ free -m
total used free shared buff/cache available
Mem: 386758 3750 1947 25283 381060 355675
Swap: 131071 3194 127877
硬盘大约3.5T,其中已经使用了2.9T。
答案 0 :(得分:1)
MongoDB非常好。问题是,它设计为水平缩放,而不是垂直缩放。这意味着如果您的数据库持有大量数据,您应该对集合进行分片以实现更好的并行化。
关于查询时间的差异,我不认为您的分析是确凿的。 DB可能位于不同的机器上(具有不同的规格)。假设硬件是相同的,DB2显然在其集合上保存了更多文档,并且两个DB上的文档大小不同。相同的查询可以返回不同大小的数据集。这将不可避免地对数据序列化和其他低级方面产生影响。除非您在更加可控的设置中分析查询,否则我认为您的结果非常期待。
如果您在文档中使用DRef,请务必小心。可能的Mongo会自动取消引用它们;这意味着更多的数据要序列化和开销。
尝试使用limit
规范运行相同的查询。您已将索引定义为唯一,但我不知道是否自动使Mongo在找到值后停止索引遍历。检查db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}})
和db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}}).limit(1)
是否同时运行。
查看Indexes on embedded fields和Indexes on embedded documents。嵌入式文档似乎会削弱额外的开销。
最后,如果您的文档没有嵌入文档,只有嵌入字段(这似乎是这种情况),那么更具体地定义您的索引。创建此索引
db.coll1.createIndex({"id.pid.f1": 1, "id.pid.f2": 1}, {unique: true})
再次运行查询。如果这个索引没有提高性能,那么我相信你已经做好了一切,可能是时候开始sharding了。