结论:面对大量不需要作为中间值计算,仅是作为记录存下来的信息建议使用string字符串存储,而不直接使用字典,列表等结构直接存入数据库。
mongodb的文档具有很好的拓展性,给我们存储带来了便利, 但是当数据量到达一定范围后,比如我在使用中,达到1000W条记录,或者存储大小超过5G之后,就不得不考虑一下优化问题。做了一个简单的测试,代码如下。
测试对象:用string存储与用字典dict存储对比
测试方法:模拟5w个字段,第一种方法拼接为一个大的string串存储数据,比如&1718-0-0-0&1882-1-1-1, 另一种用字典存储{1718: [0, 0, 0], 1882: [1, 1, 1]} 然后利用循环插入5000条重复记录。 测试查询的时候,遍历每一条记录。
测试环境:win8.1 4G内存 东芝SSD128G(如果代码运行结果差异可能是固态硬盘和机械硬盘的差异) 查询工具:MongoVUE mongodb 2.6.3
测试代码:
<span style="font-size:18px;">__author__ = 'CRay'
import pymongo
import random
def test():
db = conn.test
str_a = ''
for i in range(0, 49999):
str_a += '&' + str(i) + '-1-0-0'
for i in range(0, 4999):
db.insert({'a': str_a, 'num': i})
db.create_index('num')
def test_list():
db = conn.test1
list_a = {}
for i in range(0, 49999):
list_a[str(i)] = [1, 0, 0]
for i in range(0, 4999):
db.insert({'a': list_a, 'num': i})
db.create_index('num')
def update():
db = conn.test1
list_num = []
for i in range(0, 99):
num = random.randrange(1, 29999)
list_num.append(num)
logs = db.find()
count = 0
for log in logs:
try:
if log['num'] in list_num:
print log['num'],
count += 1
except Exception as e:
print e
print count
if __name__ == '__main__':
client = pymongo.Connection()
conn = client.test
import profile
profile.run("update()")</span>
==============================分割线==================================
结果:可见效率非常明显。 string对应test, dict对应test1
原因分析:
猜测在存储list或者ditc结构时,虽然mongodb直接使用BSON格式,但是依旧需要保留数据信息,比如键值对信息等,这占据了空间,也导致查询变慢。 这需要查看mongodb的文档,具体下一篇再讲。
===========================结果截图=========================
整个过程还有很多细节有待考究,其中错误希望指出!
完