MongoDB数据库查询性能提高40倍的经历分享
前言
数据库性能对软件整体性能有着至关重要的影响,本文给大家分享了一次MongoDB数据库查询性能提高40倍的经历,感兴趣的朋友们可以参考学习。
背景说明
1、数据库:MongoDB
2、数据集:
A:字段数不定,这里主要用到的两个UID和Date
B:三个字段,UID、Date、Actions。其中Actions字段是包含260元素JSON数组,每个JSON对象有6个字段。共有数据800万条左右。
通过组合条件从A数据表查询出(UID,Date)列表,最多可能包含数万条记录;
然后用第1步的结果从B中查询出对应的数据
用第2步结果去Actions的某个固定位置的元素的进行计算
for a_doc in a _docs:
b_doc = db.b.find_one({"uid":a_doc["uid"], "date": a_doc["date"]})
# 只有能查到相应的结果时,才可以
if b_doc is not None:
total += b_doc["actions"][20]["number"]
count += 1
# 求平均数
if count 0 :
avg = total/count
实现难度当然是最低的,可是整个任务在第一步只有1万条左右的返回时,消耗的时间竟然达到了惊人38秒。当然这是已经加了索引的结果,否则可能都无法得到结果了。
减少查询次数
瓶颈显而易见,在循环中查询Collection B,增加了网络开销,自然也就增加时间,如果一次查询出所有结果,自然会大大提高效率。也就是说,我要把第一步的结果作为条件一次性传递,做一个$in操作。可是怎么才能做到呢?如果在uid和date上分别做$in操作,那么返回的结果就会是二者单独做$操作的合集,很显然这和要求是不符的。
经过上面的分析,似乎进入了死胡同。其实答案也基本显现了,需要有一个字段可以满足上面的要求,那么这个字段就是uid和date的合体,就命名为uid_date。uid_date是一个新字段,在B中并不存在,在使用之前需要将数据库现有的数据做一下处理。
处理完毕改造程序:
# 下面的只体现和本次修改相关的内容 uid_date_list = [] for a_doc in a_docs: uid_date_list.append(a_doc["uid"] + "_" + a_doc["date"]) # 查询B b_cursor = db.b.find({"uid_date":{"$in":uid_date_list}}) # 下面就是取出结果,求平均数 ...
这一番改造颇费时间,主要是前期的数据处理。代码改造完毕,执行下看看吧。
可是,可是…… 45秒
我做错了什么?!
增加返回记录数
我还是坚信上面的优化思路是对的,现在看看数据库能给一些什么线索吧。
登录到数据库服务器,找到MongoDB的日志/data/mongodb/logs/mongod.log。仔细查找,发现在查询数据集B时有很多getMore命令。这就奇怪了,我是一次性查询,为什么还有getMore。
赶紧查下官方的文档,然后发现了下面的内容:
batcSize参数指定了每次返回的个数,默认的101个。那看来这个应该是问题所在。找下pymongo的文档,也可以设置这个参数,那就设个大的吧10000。
再次改造程序如下:
# 增加batch_size b_cursor = db.b.find({"uid_date":{"$in": uid_date_list}}, batch_size=10000)
这次总该可以了。
嗯,好了一些,降到了20秒左右。可是,这离1秒只能还差距20倍呢。
返回值减负
当日不能放弃,继续通过日志查找线索,发现还是有很多getMore。通过各方查找,发现mongodb每次最多返回16M的记录,通过getMore日志的比对,发现的确如此。由于B中每条记录的过去庞大,每次只能几百条记录,因此要一次多返回,那就必须要减少每次返回的记录数。因为在计算时,只用了特定索引位置上的数据,所以只返回该条记录就可以了。
最后的代码就不再写了,具体可以参考官方文档的实例。
总结
本篇文章到此结束,如果您有相关技术方面疑问可以联系我们技术人员远程解决,感谢大家支持本站!
我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题
本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 MongoDB数据库查询性能提高40倍的经历分享
相关文章
- mongoDB数据库备份恢复 之 mongodb 4.2.8备份恢复与导出导入
- MongoDB的文档、集合、数据库(二)详解数据库
- MongoDB 更新文档详解数据库
- NoSQL数据库MongoDB:NoSQL数据库的首选(mongodb等于)
- 查询MongoDB实现关联查询的技巧(mongodb关联)
- MongoDB强力支持实时数据同步(mongodb实时同步)
- 分页查询MongoDB中多条件实现高效分页查询(mongodb多条件)
- 实现PHP与MongoDB的桥梁:连接数据库(php连接mongodb)
- MongoDB组合索引:优化查询性能的最佳利器(mongodb组合索引)
- 面试挑战:如何掌握MongoDB(面试题mongodb)
- 使用MongoDB轻松实现企业数据持久存储(数据库mongodb)
- 题MongoDB面试指南:准备技能清单(mongodb的面试)
- 快速释放MongoDB连接的简单方法(mongodb连接释放)
- 百度推广Mongodb数据库的优势(百度mongodb)
- 历史悠久的MongoDB:存储着未知历史记载(历史数据mongodb)
- MongoDB简介:非关系型数据库的神奇之处(mongodb简介)
- Mongodb数据库:高性能、高可扩展性的NoSQL数据库(mongodb数据库介绍)
- MongoDB工具类:快速解决数据库开发难题(mongodb工具类)
- 构建MongoDB索引:增强性能与提高效率(mongodb创建索引)
- 解决MongoDB查询性能的方法(mongodb查询很慢)
- 如何快速重新启动 MongoDB 数据库服务(mongodb重启服务)
- Mongodb中文网:数据库管理利器的必备指南(mongodb中文网)
- Mastering MongoDB: Essential Tips and Tricks for Efficient Database Operations(mongodb数据库操作)
- MongoDB数据库优化技巧与方法(mongodb调优)
- MongoDB启动命令,快速搭建数据库环境(mongodb启动命令)
- 深入浅出:MongoDB中的查询语句(mongodb 查询语句)
- MongoDB内存优化:如何配置更高的性能(mongodb内存配置)