mongodb 搜索速度_MongoDB数据库查询性能提高40倍的经历分享

前言

数据库性能对软件整体性能有着至关重要的影响,本文给大家分享了一次MongoDB数据库查询性能提高40倍的经历,感兴趣的朋友们可以参考学习。

背景说明

1、数据库:MongoDB

2、数据集:

A:字段数不定,这里主要用到的两个UID和Date

B:三个字段,UID、Date、Actions。其中Actions字段是包含260元素JSON数组,每个JSON对象有6个字段。共有数据800万条左右。

3、业务场景:求平均数

通过组合条件从A数据表查询出(UID,Date)列表,最多可能包含数万条记录;

然后用第1步的结果从B中查询出对应的数据

用第2步结果去Actions的某个固定位置的元素的进行计算

进化过程

在这里使用Python演示

最直接想到的方法

根据上面的业务场景描述,最容易想到的解决方法就是

from pymongo import MongoClient

# 连接数据库

db = MongoClient('mongodb://127.0.0.1:27017')['my_db']

# 简化的查询数据集A的条件

filter = {...}

# 查询Collection A

a_cursor = db.a.find(_filter)

a_docs = [x for x in a_cursor]

# 变量的初始定义

count = 0

total = 0

# 加入需要用到的元素为第21个

index = 20

# 查询Collection B,同时做累加

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中每条记录的过去庞大,每次只能几百条记录,因此要一次多返回,那就必须要减少每次返回的记录数。因为在计算时,只用了特定索引位置上的数据,所以只返回该条记录就可以了。

最后的代码就不再写了,具体可以参考官方文档的实例。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/503511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

signature=8405d26e250ad07c44560263cb1d4fc0,Systems for analyzing microtissue arrays

摘要:A tissue microarray imaging system autonomously images, analyzes, and stores data for samples in a tissue microarray. The system may include a tissue microarray, a robotic microscope, and an imaging workstation that executes software to aut…

ios支付宝支付失败不回调_为什么 iOS 支付成功后能回到 APP ,但是没有回调?...

接入客户端从服务器端拿到 charge 对象后,调用下面的方法[Pingpp createPayment:chargeviewController:viewControllerappURLScheme:kUrlSchemewithCompletion:^(NSString *result, PingppError *error) {if ([result isEqualToString:"success"]) { …

html如何将设置文本效果,css如何对文本进行修饰

color属性:设置文本文字颜色。用法如下:color:颜色值;color属性可以设置的合法颜色值包括:16进制颜色值(例:#ffffff),rgb颜色值【例:rgb(0,0,0)】,rgba颜色值【例:rgb(0,…

HTML与cgi post传递与接收,CGI实例--表单GET与POST示例

CGI概述CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI程 序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互, 也就是CGI程序通过读标准输入,接受Web浏览器发送给Web服务器的信息, 进行处理, 将响应结果再通过…

vue横向树结构_vue树形结构的实现

1. 主要代码使用单文件组件的方式, 需要一个父组件treeMenu, 和子组件treeItem1.1 父组件treeMenu.vue:nodes"treeData">export default {name: treeMenu,data: () > {return {treeData: {label: china,nodes: [{label: hubei,nodes: [{label: wuhan},{label: …

cesium js 路径_vue2.0项目集成Cesium的实现方法

安装cesium在已有项目中执行,npm i cesium修改配置build/webpack.base.conf.js1、定义 Cesium 源码路径const cesiumSource ../node_modules/cesium/Sourceuse strictconst path require(path)const utils require(./utils)const config require(../config)const vueLoader…

pytorch模型加载测试_pytorch模型加载方法汇总

Pytorch有很多方便易用的包,今天要谈的是torchvision包,它包括3个子包,分别是: torchvison.datasets ,torchvision.models ,torchvision.transforms ,分别是预定义好的数据集(比如MNIST、CIFAR1…

android studio聊天跳转_Android 第三方应用跳转到QQ进行聊天

跳转QQ聊天代码十分简单&#xff1a;//获取包信息public static booleanisQQClientAvailable(Context context) {finalPackageManager packageManager context.getPackageManager();List pinfo packageManager.getInstalledPackages(0);if(pinfo !null) {for(inti 0;i < p…

html字体闪烁模板,CSS+JS阴影闪烁文字

阴影闪烁文字.F1 {filter: glow(Color#FF8000,Strength10);width150px;height200px;}.F2 {filter: glow(Color#00FF00,Strength9);width110px;height200px;}.F3 {filter: glow(Color#0080FF,Strength12);width90px;height200px;}var rate 500var i 0var F F1function doThin…

html 规定换行,HTML 换行

css3整理--clipclip语法: .selector { clip: rect | auto | inherit } 注意:clip属性只能在元素设置了“position:absolute”或者“position:fi ...Android 边框圆角RelativeLayout 圆角实现: drawable目录下面定义shape的xml文件: mall_header_rel_bg.xml <?xml version&…

qt执行命令行失败_QT缺少 qtcore4.dll,debug下运行不成功

刚装QT的时候&#xff0c;好像我的环境变量没有设置好&#xff0c;哎&#xff0c;。隐患终于爆发了。在VS下运行成功的QT程序&#xff0c;然后点击Debug下的.exe&#xff0c;老提示缺少Qtcore4.dll&#xff0c;当时正郁闷之极&#xff0c;忘了怎样在网页上查找&#xff0c;只是…

伪类如何动态在html设置样式,用js实现before和after伪类的样式修改的示例代码

本文介绍了使用javascript,jQuery实现修改before,after伪类的样式&#xff0c;分享给大家&#xff0c;具体如下&#xff1a;最近遇到一个需要改变:before,:after 伪类的样式&#xff0c;发现css中并不能直接选择某一个元素的:before和:after伪类元素&#xff0c;所以特总结了使…

html 图片平移动画,CSS3 圆圈内图片的自动平移/旋转动画

CSS语言&#xff1a;CSSSCSS确定body {background: #fbfbfb;}.spinner {width: 155px;height: 155px;border-radius: 100%;background-color: #d8d8d8;border: 10px solid #575757;position: absolute;top: 50%;left: 50%;transform: translateX(-50%) translateY(-50%) transl…

layui option 动态添加_layui select动态添加option的实例

html产品类别轻松融容易融快乐融增加产品类别js//重新渲染表单function renderForm(){layui.use(form, function(){var form layui.form();//高版本建议把括号去掉&#xff0c;有的低版本&#xff0c;需要加()form.render();});}//增加产品类别按钮点击事件function addProduc…

html鼠标滑轮换图片,JavaScript实现鼠标滚轮控制页面图片切换

鼠标上的滚轮是一个不错的东东&#xff0c;为什么这么说&#xff0c;因为它能帮助我们快速的浏览网页,快速的进行长篇文章的阅读。对于web前端的我们来说又怎么能不注重这个鼠标滚轮呢&#xff0c;那么它能如何让用户更好的浏览网页呢&#xff1f;本文主要介绍JavaScript实现鼠…

html无法引入less样式,@import less样式文件 只有css样式生效, less样式却不生效

使用webp享。发概程间告屏会。一控近到都从述序也问ack构建项目时 import less文件时 为什么只有文件里面css样式生效&#xff0c; less样式却不生支器事的后功发久这含层请间业在屏有随些气和域&#xff0c;实按控幻近持的前时来能过后些的处求也务浏蔽等机站风滚或默现钮制灯…

minio存储类型 归档管理页面_minio分布式存储系列(一)__介绍及开箱使用

minio分布式存储系列(一)__介绍及开箱使用简介&#xff1a;Minio 是一个基于Go语言编写的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;可以理解为是S3的开源版本(亚马逊S3&#xff1a;专为从任意位置存储和检索任意数量的数据而构建的对象存储&#xff0c;官网地址…

电脑视频html5全屏掉帧,Windows 10使用自带的电影和电视全屏看视频时掉帧(画面卡顿)...

Windows 10自带的“电影和电视”应用能应付一些常见的视频格式&#xff0c;还能播放360度全景视频&#xff0c;对部分人来说用它就够了&#xff0c;不需要额外安装其它播放视频的应用。在使用电影和电视全屏播放视频的过程中&#xff0c;部分人可能会出现掉帧情况&#xff0c;画…

hadoop job 数量_Hadoop job任务分配

1. 必要性Hadoop提供了多个配置参数使得admin和user可以灵活设定内存&#xff1b;有些参数有defaut-value, 有些选项是cluster specific以支持memory-intensive作业。当构建一个cluster时&#xff0c;admin可以先设定一些appropriate default value&#xff1b;其他一些参数设定…

计量经济学计算机输出结果,计量经济学作业答案A..doc

计量经济学作业答案A.计量经济学(本科)第一次作业(First Assignment) 答案问题1某一元回归模型y ?0 ?1 x u 中 ?1 的估计量(OLS法-最小二乘法)用表示。检验 ?1 0的t统计量定义为 t &#xff0c;其中S()为的样本标准差(Standard Error)。问题&#xff1a;1) 请找出t统计…