MongoDB插入速度权衡
简而言之: 当我把一个包含很多字段的JSON对象放在MongoDB的一个字符串字段里,和把JSON对象的每个字段放在MongoDB的独立字段里时,插入速度差别很大。1) 这种差别正常吗?2) 这些插入速度算不算典型?
我有很多记录,每条记录都有一个独特的字符串ID和600个整数值。这些记录已经以JSON对象的形式保存在一个文件里——每个文档占一行。如果我把MongoDB的文档表示为一组整数字段,并把我的唯一ID放到MongoDB的_id
字段里,我大约能每秒插入50条文档。如果我只创建一个包含两个字段的文档(_id
是唯一字符串ID,val
是一个字符串,里面保存了整条JSON记录),我能每秒插入100条文档。
我使用的是Python客户端,并尝试过批量插入(比如一次插入10条、100条、1000条)。这种差别一直存在。这种情况是正常的吗? 我天真地以为不会有差别,因为MongoDB本身把记录存储为BSON,实际上在有600个整数的字段和一个包含600个整数的JSON字符串之间应该没有太大区别。
补充说明:1) 在这两种情况下,我都把JSON转换成字典,以确保这不会影响速度测量(也就是使用json.loads
等)。换句话说,在单字段的JSON字符串情况下,我做的所有操作和另一种情况一样,只是忽略了转换后的字典。
2) 我还尝试过一次干跑,所有操作保持不变但不插入到MongoDB。我每秒能处理大约700-800行。
3)
a. db.test.stats() in single-line-single field case (i.e. fast case):
{
"ns" : "tmp.test",
"count" : 7999,
"size" : 71262392,
"avgObjSize" : 8908.91261407676,
"storageSize" : 88751616,
"numExtents" : 9,
"nindexes" : 1,
"lastExtentSize" : 21742848,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 466944,
"indexSizes" : {
"_id_" : 466944
},
"ok" : 1
}
b. db.test.stats() (each column to a separate case; i.e., slow case):
{
"ns" : "tmp.test",
"count" : 7999,
"size" : 85710500,
"avgObjSize" : 10715.15189398675,
"storageSize" : 107561984,
"numExtents" : 9,
"nindexes" : 1,
"lastExtentSize" : 26091264,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 466944,
"indexSizes" : {
"_id_" : 466944
},
"ok" : 1
}
1 个回答
如果可以的话,建议开启C扩展,因为这样会大大提升性能。我觉得速度差异的原因是需要序列化的键数量比较多(因为你没有开启扩展,所以是用纯Python代码来处理),这会把数据转换成BSON文档。开启C扩展后,这个过程会快很多(但还是需要进行),所以我猜你在两种方法之间还是会看到(非常微小的)速度差异。
编辑:我提到的“开启C扩展”是指重新构建pymongo,或者使用一个已经为你的平台构建好的二进制文件,这个文件里包含了C模块。你可以在http://pypi.python.org/pypi/pymongo/2.0.1#downloads查看可用的二进制包。