MongoDB數據庫查詢性能提高40倍

MongoDB數據庫查詢性能提高40倍

大家在使用 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.pswp.cn/news/390007.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390007.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390007.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通過Ajax方式上傳文件(input file),使用FormData進行Ajax請求

<script type"text/jscript">$(function () {$("#btn_uploadimg").click(function () {var fileObj document.getElementById("FileUpload").files[0]; // js 獲取文件對象if (typeof (fileObj) "undefined" || fileObj.size …

并發插入數據庫會導致失敗嗎_會導致業務失敗的數據分析方法

并發插入數據庫會導致失敗嗎The true value of data depends on business insight.Data analysis is one of the most powerful resources an enterprise has. However, if the tools and processes used are not friendly and widely available to the business users who nee…

434. 字符串中的單詞數

434. 字符串中的單詞數 統計字符串中的單詞個數&#xff0c;這里的單詞指的是連續的不是空格的字符。 請注意&#xff0c;你可以假定字符串里不包括任何不可打印的字符。 示例: 輸入: “Hello, my name is John” 輸出: 5 解釋: 這里的單詞是指連續的不是空格的字符&#x…

zooland 新開源的RPC項目,希望大家在開發的微服務的時候多一種選擇,讓微服務開發簡單,并且容易上手。...

zooland 我叫它動物園地&#xff0c;一個構思很長時間的一個項目。起初只是覺得各種通信框架都封裝的很好了&#xff0c;但是就是差些兼容&#xff0c;防錯&#xff0c;高可用。同時在使用上&#xff0c;不希望有多余的代碼&#xff0c;像普通接口一樣使用就可以了。 基于這些想…

187. 重復的DNA序列

187. 重復的DNA序列 所有 DNA 都由一系列縮寫為 ‘A’&#xff0c;‘C’&#xff0c;‘G’ 和 ‘T’ 的核苷酸組成&#xff0c;例如&#xff1a;“ACGAATTCCG”。在研究 DNA 時&#xff0c;識別 DNA 中的重復序列有時會對研究非常有幫助。 編寫一個函數來找出所有目標子串&am…

牛客網_Go語言相關練習_選擇題(2)

注&#xff1a;題目來源均出自牛客網。 一、選擇題 Map&#xff08;集合&#xff09;屬于Go的內置類型&#xff0c;不需要引入其它庫即可使用。 Go-Map_菜鳥教程 在函數聲明中&#xff0c;返回的參數要么都有變量名&#xff0c;要么都沒有。 C選項函數聲明語法有錯誤&#xff0…

機器學習模型部署_9月版部署機器學習模型

機器學習模型部署每月版 (MONTHLY EDITION) Often, the last step of a Data Science task is deployment. Let’s say you’re working at a big corporation. You’re building a project for a customer of the corporation and you’ve created a model that performs well…

352. 將數據流變為多個不相交區間

352. 將數據流變為多個不相交區間 給你一個由非負整數 a1, a2, …, an 組成的數據流輸入&#xff0c;請你將到目前為止看到的數字總結為不相交的區間列表。 實現 SummaryRanges 類&#xff1a; SummaryRanges() 使用一個空數據流初始化對象。void addNum(int val) 向數據流中…

Java常用的八種排序算法與代碼實現

排序問題一直是程序員工作與面試的重點&#xff0c;今天特意整理研究下與大家共勉&#xff01;這里列出8種常見的經典排序&#xff0c;基本涵蓋了所有的排序算法。 1.直接插入排序 我們經常會到這樣一類排序問題&#xff1a;把新的數據插入到已經排好的數據列中。將第一個數和第…

熊貓ai智能機器人量化_機器學習中的熊貓是什么

熊貓ai智能機器人量化Machine learning is a complex discipline. The implementation of machine learning models is now far much easier than it used to be, this is as a result of Machine learning frameworks such as pandas. Wait!! isnt panda an animal? As I rec…

441. 排列硬幣

441. 排列硬幣 你總共有 n 枚硬幣&#xff0c;并計劃將它們按階梯狀排列。對于一個由 k 行組成的階梯&#xff0c;其第 i 行必須正好有 i 枚硬幣。階梯的最后一行 可能 是不完整的。 給你一個數字 n &#xff0c;計算并返回可形成 完整階梯行 的總行數。 示例 1&#xff1a;…

調用百度 Echarts 顯示重慶市地圖

因為 Echarts 官方不再提供地圖數據的下載&#xff0c;在這里保存一份&#xff0c;供日后使用&#xff0c;重慶地圖數據的 JSON 文件在 CSDN 上下載。 <!DOCTYPE html> <html style"height: 100%"><head><meta charset"utf-8"><…

JEESZ-SSO解決方案

2019獨角獸企業重金招聘Python工程師標準>>> 第一節&#xff1a;單點登錄簡介 第一步&#xff1a;了解單點登錄 SSO主要特點是: SSO應用之間使用Web協議(如HTTPS)&#xff0c;并且只有一個登錄入口. SSO的體系中有下面三種角色: 1) User(多個) 2) Web應用(多個) 3) …

女朋友天天氣我怎么辦_關于我的天氣很奇怪

女朋友天天氣我怎么辦帶有扭曲的天氣應用 (A Weather App with a Twist) Is My Weather Weird?? is a weather app with a twist — it offers a simple answer to a common question we’ve all asked. To do this we look at how often weather like today’s used to happ…

Java中length,length(),size()的區別

&#xff08;一&#xff09;區別&#xff1a; ①length&#xff1a;用于算出數組的長度。 ②length&#xff08;&#xff09;&#xff1a;用于找出字符串的長度。 ③size&#xff08;&#xff09;&#xff1a;用于找出泛型集合的元素個數。轉載于:https://www.cnblogs.com/not-…

5895. 獲取單值網格的最小操作數

5895. 獲取單值網格的最小操作數 給你一支股票價格的數據流。數據流中每一條記錄包含一個 時間戳 和該時間點股票對應的 價格 。 不巧的是&#xff0c;由于股票市場內在的波動性&#xff0c;股票價格記錄可能不是按時間順序到來的。某些情況下&#xff0c;有的記錄可能是錯的…

為什么要用Redis

最近閱讀了《Redis開發與運維》&#xff0c;非常不錯。這里對書中的知識整理一下&#xff0c;方便自己回顧一下Redis的整個體系&#xff0c;來對相關知識點查漏補缺。我按照五點把書中的內容進行一下整理&#xff1a;為什么要選擇Redis&#xff1a;介紹Redis的使用場景與使用Re…

第一次馬拉松_成為數據科學家是一場馬拉松而不是短跑

第一次馬拉松Since Data Science became the “Sexiest Job of the 21st Century” the interest in the field has grown tremendously. With it so have the courses available to gain the necessary knowledge. As great as this is, the downside is a field marketed as …

273. 整數轉換英文表示

273. 整數轉換英文表示 將非負整數 num 轉換為其對應的英文表示。 示例 1&#xff1a;輸入&#xff1a;num 123 輸出&#xff1a;"One Hundred Twenty Three" 示例 2&#xff1a;輸入&#xff1a;num 12345 輸出&#xff1a;"Twelve Thousand Three Hundred…

Java-運算符

算術運算符 加法 相加運算符兩側的值- 減法 左操作數減去右操作數* 乘法 相乘操作符兩側的值/ 除法 左操作數除以右操作數&#xff08;int類型的數相除時&#xff0c;會得到int類型的值&#xff0c;如果結果有小數&#xff0c;則小數部分會被舍棄&#xff09;% 模余運算&…