色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何從MySQL數據庫里讀取100w數據行進行處理呢?

數據分析與開發 ? 來源:CSDN ? 2023-03-17 17:13 ? 次閱讀

背景

大數據量操作的場景大致如下:

數據遷移

數據導出

批量處理數據

在實際工作中當指定查詢數據過大時,我們一般使用分頁查詢的方式一頁一頁的將數據放到內存處理。但有些情況不需要分頁的方式查詢數據或分很大一頁查詢數據時,如果一下子將數據全部加載出來到內存中,很可能會發生OOM(內存溢出);而且查詢會很慢,因為框架耗費大量的時間和內存去把數據庫查詢的結果封裝成我們想要的對象(實體類)。

舉例:在業務系統需要從 MySQL 數據庫里讀取 100w 數據行進行處理,應該怎么做?

做法通常如下:

常規查詢: 一次性讀取 100w 數據到 JVM 內存中,或者分頁讀取

流式查詢: 建立長連接,利用服務端游標,每次讀取一條加載到 JVM 內存(多次獲取,一次一行)

游標查詢: 和流式一樣,通過 fetchSize 參數,控制一次讀取多少條數據(多次獲取,一次多行)

常規查詢

默認情況下,完整的檢索結果集會將其存儲在內存中。在大多數情況下,這是最有效的操作方式,并且由于 MySQL 網絡協議的設計,因此更易于實現。

舉例:假設單表 100w 數據量,一般會采用分頁的方式查詢:

@Mapper
publicinterfaceBigDataSearchMapperextendsBaseMapper{

@Select("SELECTbds.*FROMbig_data_searchbds${ew.customSqlSegment}")
PagepageList(@Param("page")Pagepage,@Param(Constants.WRAPPER)QueryWrapperqueryWrapper);

}

注:該示例使用的 MybatisPlus。

該方式比較簡單,如果在不考慮 LIMIT 深分頁優化情況下,估計你的數據庫服務器就噶皮了,或者你能等上幾十分鐘或幾小時,甚至幾天時間檢索數據。

流式查詢

流式查詢指的是查詢成功后不是返回一個集合而是返回一個迭代器,應用每次從迭代器取一條查詢結果。流式查詢的好處是能夠降低內存使用。

如果沒有流式查詢,我們想要從數據庫取 100w 條記錄而又沒有足夠的內存時,就不得不分頁查詢,而分頁查詢效率取決于表設計,如果設計的不好,就無法執行高效的分頁查詢。因此流式查詢是一個數據庫訪問框架必須具備的功能。

MyBatis 中使用流式查詢避免數據量過大導致 OOM ,但在流式查詢的過程當中,數據庫連接是保持打開狀態的,因此要注意的是:

執行一個流式查詢后,數據庫訪問框架就不負責關閉數據庫連接了,需要應用在取完數據后自己關閉。

必須先讀?。ɑ蜿P閉)結果集中的所有行,然后才能對連接發出任何其他查詢,否則將引發異常。

MyBatis 流式查詢接口

MyBatis 提供了一個叫 org.apache.ibatis.cursor.Cursor 的接口類用于流式查詢,這個接口繼承了 java.io.Closeable 和 java.lang.Iterable 接口,由此可知:

Cursor 是可關閉的;

Cursor 是可遍歷的。

除此之外,Cursor 還提供了三個方法:

isOpen(): 用于在取數據之前判斷 Cursor 對象是否是打開狀態。只有當打開時 Cursor 才能取數據;

isConsumed(): 用于判斷查詢結果是否全部取完。

getCurrentIndex(): 返回已經獲取了多少條數據

使用流式查詢,則要保持對產生結果集的語句所引用的表的并發訪問,因為其查詢會獨占連接,所以必須盡快處理。

為什么要用流式查詢?

如果有一個很大的查詢結果需要遍歷處理,又不想一次性將結果集裝入客戶端內存,就可以考慮使用流式查詢;

分庫分表場景下,單個表的查詢結果集雖然不大,但如果某個查詢跨了多個庫多個表,又要做結果集的合并、排序等動作,依然有可能撐爆內存;詳細研究了sharding-sphere的代碼不難發現,除了group by與order by字段不一樣之外,其他的場景都非常適合使用流式查詢,可以最大限度的降低對客戶端內存的消耗。

游標查詢

對大量數據進行處理時,為防止內存泄漏情況發生,也可以采用游標方式進行數據查詢處理。這種處理方式比常規查詢要快很多。

當查詢百萬級的數據的時候,還可以使用游標方式進行數據查詢處理,不僅可以節省內存的消耗,而且還不需要一次性取出所有數據,可以進行逐條處理或逐條取出部分批量處理。一次查詢指定 fetchSize 的數據,直到把數據全部處理完。

Mybatis 的處理加了兩個注解:@Options 和 @ResultType

@Mapper
publicinterfaceBigDataSearchMapperextendsBaseMapper{

//方式一多次獲取,一次多行
@Select("SELECTbds.*FROMbig_data_searchbds${ew.customSqlSegment}")
@Options(resultSetType=ResultSetType.FORWARD_ONLY,fetchSize=1000000)
PagepageList(@Param("page")Pagepage,@Param(Constants.WRAPPER)QueryWrapperqueryWrapper);

//方式二一次獲取,一次一行
@Select("SELECTbds.*FROMbig_data_searchbds${ew.customSqlSegment}")
@Options(resultSetType=ResultSetType.FORWARD_ONLY,fetchSize=100000)
@ResultType(BigDataSearchEntity.class)
voidlistData(@Param(Constants.WRAPPER)QueryWrapperqueryWrapper,ResultHandlerhandler);

}

@Options

ResultSet.FORWORD_ONLY:結果集的游標只能向下滾動

ResultSet.SCROLL_INSENSITIVE:結果集的游標可以上下移動,當數據庫變化時,當前結果集不變

ResultSet.SCROLL_SENSITIVE:返回可滾動的結果集,當數據庫變化時,當前結果集同步改變

fetchSize:每次獲取量

@ResultType

@ResultType(BigDataSearchEntity.class):轉換成返回實體類型

注意:返回類型必須為 void ,因為查詢的結果在 ResultHandler 里處理數據,所以這個 hander 也是必須的,可以使用 lambda 實現一個依次處理邏輯。

注意:

雖然上面的代碼中都有 @Options 但實際操作卻有不同:

方式一是多次查詢,一次返回多條;

方式二是一次查詢,一次返回一條;

原因:

Oracle 是從服務器一次取出 fetch size 條記錄放在客戶端,客戶端處理完成一個批次后再向服務器取下一個批次,直到所有數據處理完成。

MySQL 是在執行 ResultSet.next() 方法時,會通過數據庫連接一條一條的返回。flush buffer 的過程是阻塞式的,如果網絡中發生了擁塞,send buffer 被填滿,會導致 buffer 一直 flush 不出去,那 MySQL 的處理線程會阻塞,從而避免數據把客戶端內存撐爆。

非流式查詢和流式查詢區別:

非流式查詢:內存會隨著查詢記錄的增長而近乎直線增長。

流式查詢:內存會保持穩定,不會隨著記錄的增長而增長。其內存大小取決于批處理大小BATCH_SIZE的設置,該尺寸越大,內存會越大。所以BATCH_SIZE應該根據業務情況設置合適的大小。

另外要切記每次處理完一批結果要記得釋放存儲每批數據的臨時容器,即上文中的gxids.clear();





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2974

    瀏覽量

    104981
  • MySQL
    +關注

    關注

    1

    文章

    829

    瀏覽量

    26678
  • JVM
    JVM
    +關注

    關注

    0

    文章

    158

    瀏覽量

    12252
  • MYSQL數據庫
    +關注

    關注

    0

    文章

    96

    瀏覽量

    9423

原文標題:面試官:從 MySQL 讀取 100w 數據進行處理,應該怎么做?

文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    怎么簡單實現由Labview讀取的串口數據自增寫入mysql5.7數據庫中?

    怎么簡單實現由Labview讀取的串口數據自增寫入mysql5.7數據庫中? 已實現:串口數據的接收
    發表于 01-11 22:05

    求大神現身,如何讀取數據庫里指定的文件?

    大神們,如何讀取數據庫里指定的文件?我的數據庫里記錄了特征值,是按日期存儲的,如何讀取某一段時間內的特征值內容?比如我要設置一個日期起始輸入框,就能
    發表于 03-22 11:54

    【EVB-335X-II試用體驗】之QT遠程操作MySql數據庫圖片數據的寫入與讀取

    數據保存到MySql數據庫中。點擊“讀取圖片”,QT程序遠程數據庫服務器
    發表于 07-10 22:49

    labview插入數據MySQL數據庫

    最近在用labview寫入數據MySQL數據庫,遇到一個問題:(如圖片所示)利用insert指令插入數據,為什么每次插入單個值都會新起一行,而不會自動插入在連續的非空下一行
    發表于 12-26 16:52

    數據庫讀取數據問題

    本帖最后由 控制發燒友 于 2020-7-9 08:48 編輯 如圖所示,我想讀取MySQL數據庫里數據,當我字段設置成字符串形式A B C時
    發表于 07-09 08:46

    MySQL數據庫Access存儲讀取SQL語句

    LabVIEW視頻教程MySQL數據庫Access存儲讀取SQL語句
    發表于 10-21 11:59

    MySQL端口可以MySQL數據庫中存儲和檢索數據

    MySQL端口可以MySQL數據庫中存儲和檢索數據。 概覽 建立連接后,端口讀取
    的頭像 發表于 02-15 14:07 ?1698次閱讀

    華為云數據庫-RDS for MySQL數據庫

    華為云數據庫-RDS for MySQL數據庫 華為云數據庫作為華為云的一款數據庫產品,它主要是以MyS
    的頭像 發表于 10-27 11:06 ?1562次閱讀

    有哪些不同的MySQL數據庫引擎?

    數據庫引擎是MySQL組件,可以處理SQL操作,例如從數據庫創建、讀取和更新數據
    的頭像 發表于 04-03 16:38 ?1167次閱讀

    python讀取數據庫數據 python查詢數據庫 python數據庫連接

    python讀取數據庫數據 python查詢數據庫 python數據庫連接 Python是一門高級編程語言,廣泛應用于各種領域。其中,Pyt
    的頭像 發表于 08-28 17:09 ?1880次閱讀

    MySQL數據庫管理與應用

    討論MySQL數據庫的管理和應用。 管理MySQL數據庫 在管理MySQL數據庫之前,我們需要了
    的頭像 發表于 08-28 17:15 ?1012次閱讀

    mysql數據庫基礎命令

    MySQL是一個流行的關系型數據庫管理系統,經常用于存儲、管理和操作數據。在本文中,我們將詳細介紹MySQL的基礎命令,并提供與每個命令相關的詳細解釋。 登錄
    的頭像 發表于 12-06 10:56 ?624次閱讀

    eclipse怎么連接數據庫mysql

    連接Eclipse和MySQL數據庫可以通過JDBC(Java Database Connectivity)來實現。以下是詳細步驟: 下載并安裝MySQL數據庫:你首先需要下載并安裝
    的頭像 發表于 12-06 11:06 ?1346次閱讀

    數據庫數據恢復—未開啟binlog的Mysql數據庫數據恢復案例

    mysql數據庫故障: 工作人員使用Delete命令刪除數據時未添加where子句進行篩選,導致全表數據被刪除,刪除后未對該表
    的頭像 發表于 12-08 14:18 ?1198次閱讀
    <b class='flag-5'>數據庫</b><b class='flag-5'>數據</b>恢復—未開啟binlog的<b class='flag-5'>Mysql</b><b class='flag-5'>數據庫</b><b class='flag-5'>數據</b>恢復案例

    MySQL數據庫的安裝

    MySQL數據庫的安裝 【一】各種數據庫的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】
    的頭像 發表于 01-14 11:25 ?114次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>數據庫</b>的安裝
    主站蜘蛛池模板: 丰满少妇被猛烈进出69影院 | 国产小视频免费在线观看 | 亚洲国产精品免费观看 | 久久综合久久鬼色 | 高h辣h双处全是肉一对一 | 激情丛林电影完整在线 | 久久学生精品国产自在拍 | 漂亮的保姆6在线观看中文 漂亮的保姆5电影免费观看完整版中文 | 最近最新中文字幕MV高清在线 | 色欲精品久久人妻AV中文字幕 | 波野结衣qvod| 久久成人免费大片 | 狠狠操天天操夜夜操 | 一级做a爰片久久毛片免费 一级做a爰片久久毛片潮喷动漫 | 久久午夜夜伦痒痒想咳嗽P 久久午夜夜伦鲁鲁片无码免费 | 欧美日韩免费播放一区二区 | 日日天干夜夜狠狠爱 | 精品国产午夜福利在线观看蜜月 | BL文库好大粗黑强强肉NP | 美女动态图真人后进式 | 91av欧美| 黄子佼81岁父亲现状曝光 | 簧片在线免费观看 | 午夜精品久久久久久99热蜜桃 | 免费韩国伦理2017最新 | 亚洲综合网国产精品一区 | 一级做a爰片久久毛片潮喷动漫 | 久久是热频国产在线 | 99精品国产免费观看视频 | 三级黄色a | 任你懆视频 这里只有精品 人与人特黄一级 | 国产高清美女一级a毛片久久w | 免费无码国产欧美久久18 | 45分钟做受片免费观看 | 男人舔女人的阴部黄色骚虎视频 | 成人在线免费观看 | 果冻传媒MV免费播放在线观看 | 国产爱豆果冻传媒在线观看视频 | 中文字幕一区二区三区在线观看 | 99精品日韩| 国内精品七七久久影院 |