MongoDB - 性能和集合大小

时间:2015-10-26 17:58:05

标签: mongodb query-performance

我对集合大小和查询性能有疑问 -

有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。

1 个答案:

答案 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 fieldsIndexes on embedded documents。嵌入式文档似乎会削弱额外的开销。

最后,如果您的文档没有嵌入文档,只有嵌入字段(这似乎是这种情况),那么更具体地定义您的索引。创建此索引

db.coll1.createIndex({"id.pid.f1": 1, "id.pid.f2": 1}, {unique: true})

再次运行查询。如果这个索引没有提高性能,那么我相信你已经做好了一切,可能是时候开始sharding了。