前言
数据库的
性能对软件的整体性能有很大的
影响。本文通过40次mondb共享提高数据库
查询性能的一种体验,感兴趣的朋友可以从中
学习。
背景描述
1。数据库:MonDB
2。数据集:
一:田的数量是不确定的,这两个主要的UID和
日期用在这里
B:三场,
用户名,日期,行动。行动领域由一个260元的JSON数组,每个JSON对象有6个字段,数据总数约800万。
三.业务场景:平均数
查询列表(UID,日期)从数据表相结合的
条件,其中可能包含了数以万计的记录。
然后根据第一步的结果从B查询相应的数据。
用第二步结果计算动作的固定
位置 进化的过程
使用Python的例子在这里
最直接的思维方式
根据上面的业务场景的描述,最简单的考虑
方法是
从pymon进口monclient
#数据库
连接 DB = monclient('mondb: / / 127.0.0.1:27017){ 'my_db}
查询数据#简化条件
筛选器…{ }
#查询集合
a_cursor = db.a.find(_filter)
a_docs = { x x a_cursor }
#变量的初始定义
数= 0
总= 0
#加入第二十一元素的需要
指数= 20
#查询集合B,同时做积累
在_docs a_doc:
b_doc = db.b.find_one({ 'uid:a_doc { 'uid},'date:a_doc { 'date} })
#只能在相应的结果
发现,它可以
如果b_doc不是没有:
总= b_doc { 'actions} { 20 } { }数
数= 1
#的平均数
如果计数> 0:
平均总数
当然,难度是最低的,但是当第一步只有1万左右时,整个
任务达到惊人的38秒。当然,这是添加到索引中的结果,否则可能无法得到结果。
减少查询的数量
瓶颈显而易见。在循环中,查询集合B增加了
网络的成本,并且自然地增加了时间。如果一个查询查询所有的结果,它将大大
提高效率,也就是说,我想把第一步的结果作为条件,做一个$
操作,但是我怎么做呢如果美元的操作是UID和日期,返回的结果将是美元的两个单独操作的组合,这与要求明显不符。
通过以上的分析,似乎已经进入了死胡同,事实上,答案基本上已经出现了。它需要一个字段来满足上述要求。这场是UID和日期的组合,并把它命名为uid_date.uid_date是一个新的领域,不存在B和
处理需要使用前。
这个过程已经完成。
以下#只和相关内容的
修改 uid_date_list = { }
对于a_doc在a_docs:
uid_date_list.append(a_doc { 'uid} + a_doc { 'date} + '_)
#查询B
b_cursor = db.b.find({ 'uid_date:{美元:uid_date_list } })
以下是#出结果,平均
…
这种
转换是相当浪费时间的,主要是早期的数据处理。让我们看一看。
但是,……45秒
我做错什么了吗!
增加返回记录的数量
我仍然认为上面的
优化思想是
正确的,现在看看数据库能提供什么线索。
登录到数据库
服务器,发现日志 / / /日志数据mondb / mond.log的mondb。仔细一看,发现有很多更多的
命令,当你查询集这是奇怪的数据,我一次性查询,为什么没有更多的。
快速
检查官方
文档,然后找到以下内容:
的batcsize
参数指定返回的数量时,
默认的101,那似乎是问题。找到pymon文档,你可以
设置这个参数。让我们成立一个大酒吧10000。
改造计划如下:
#增加batch_size
b_cursor = db.b.find({ 'uid_date:{美元:uid_date_list } },batch_size = 10000)
这次没问题。
嗯,稍微好一点,大约20秒,但距离是一秒的20倍。
返回值降低
你不能放弃的同一天,继续通过日志找到线索,发现仍有大量的多。通过各方查找,发现记录的mondb返回至一千六百万最多,这是真正的多日志的比较表明,这是真的,因为B每个记录有一个大的过去只有几百记录每一次,所以返回更多的一次,有必要减少记录的数量每次返回。因为在计算,只能用于特定的索引位置的数据,所以只能记录返回。
最终代码不再编写,可以称为正式文档的一个示例。
总结
以上就是本文的全部内容。希望本文的内容能给大家的学习或
工作带来一定的帮助。如果有任何疑问,你可以留言。