5
回答
关于Mongodb查询性能问题方面的疑惑
华为云实践训练营,热门技术免费实践!>>>   

    先来一个情景假设,假如一个文档中有很多结构,比如一个MM集合类,里面有A, B, C, D, E, F等字符串结构,然后我们主动存入了一定量的数据,此时有一个业务需求为获取某一个文档的信息,我们事先知道D的值为随机的字符串‘d34fd45f3’,当然我们也知道此要查找的文档的'_id'为‘523032cf21d7f7199037f467’。

    理论上,如果使用‘_id’来查找的话会非常的快,因为id具有一定的顺序性,能够起到索引的作用,因此会很快定位到;而如果使用查找D的值的话,理论上是会进行扫表的行为,把整个集合都扫描一遍进行比较(除了这种方法我想不出还有其他方法),因此这种方法效率应该很低才是。

    实际中,我通过添加数据的数据从10条,100条,1000条,10k条发现两种方法的操作时间上差不多,分别如下所示:

10条:   by_id:0.00072243s   by_str:0.00080101s

100条:  by_id:0.00072503s   by_str:0.00080418s

1000条:by_id:0.00073218s   by_str:0.00078892s

10K条:  by_id:0.00072598s   by_str:0.00082588s

100K条:by_id:0.00125479s    by_str:0.00142097s

    只测试到10万条数据,再大怕本本撑不住,所以没测,不过通过以上数据观察到两者方式竟然花费的时间差不多,跟理论上预测不符,这就是我非常奇怪的原因。还请各位对mongodb有些经验的大牛开导一下,多谢了。

    测试程序是使用python基于flaskext.mongoalchemy的MongoAlchemy写的,不知是否有写正确,如下:

by_id的操作是MM.query.filter(MM.mongo_id == ObjectId(‘523032cf21d7f7199037f467’)).limit(1).first()

by_str的操作是MM.query.filter(MM.D == 'd34fd45f3').limit(1).first()

//-------------------- 分割线 ------------------------------

为了感谢大家的辛苦回答,特奉上一激情图片供大家舒缓一下情绪(光看不答者,下场如此

    再补充一下:如果把写入所有文档的E项都设为相同字符‘same’的话,分别统计by_id和by_str的所有符合条件的,代码如下:

by_id的操作是MM.query.filter(MM.mongo_id == ObjectId(‘523032cf21d7f7199037f467’)).limit(1).first()

by_str的操作是f = MM.query.filter(MM.D == 'd34fd45f3');    print(f.count())

结果如下:

10条:by_id:0.00072789     by_str:0.00142216(打印count结果为10)

100条:by_id:0.00075984    by_str:0.00222587(100次)

1000条:by_id:0.00072979    by_str:0.00279903(1000次)

10K条:by_id:0.00080299    by_str:0.01343679(10K次)    

100K条:by_id:0.00074100   by_str:0.09322595(100K次)    

by_str的操作时间远小于 1次的时间次数的倍数,这更加让人疑惑了,到底mongodb在里面施了什么魔法?

举报
尼再采
发帖于4年前 5回/566阅
顶部