最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL查詢2000w超大數(shù)據(jù)的解決方法

 更新時(shí)間:2026年02月13日 09:02:01   作者:Hui  Baby  
這篇文章主要為大家詳細(xì)介紹了MySQL查詢2000w超大數(shù)據(jù)的解決方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解下

一、核心前提:MySQL 原生是否支持「流式查詢」?

MySQL 本身無服務(wù)器端流式查詢能力,僅客戶端可通過配置實(shí)現(xiàn)「流式讀取」,二者的核心區(qū)別直接決定了 2000 萬條數(shù)據(jù)查詢的異常表現(xiàn):

表格

維度服務(wù)器端客戶端(如 mysql 命令行 / JDBC)
流式能力無原生流式查詢,必須先生成完整結(jié)果集(加載到內(nèi)存 / 臨時(shí)磁盤),再向客戶端推送可通過顯式配置開啟「流式讀取」(逐行接收 / 處理),默認(rèn)是「緩沖讀取」(一次性接收全量數(shù)據(jù))
數(shù)據(jù)處理邏輯無論客戶端如何配置,服務(wù)器都會先完成所有計(jì)算(排序 / 聚合 / 全表掃描),生成完整結(jié)果集流式讀?。褐鹦薪邮?、處理后釋放內(nèi)存;緩沖讀?。阂淮涡越邮杖拷Y(jié)果集并緩存

二、2000 萬條數(shù)據(jù)查詢的異常表現(xiàn)(是否撐爆 / 觸發(fā) OOM?)

1. 服務(wù)器端:極少直接 OOM,核心問題是「IO 假死 / 超時(shí) / 磁盤飆滿」

  • 核心原因:MySQL 服務(wù)器不會將 2000 萬條數(shù)據(jù)(假設(shè)單條 1KB≈20GB)全部加載到內(nèi)存,而是將超出內(nèi)存緩沖區(qū)(sort_buffer/join_buffer)的部分寫入臨時(shí)磁盤文件;大量數(shù)據(jù)的磁盤讀寫會導(dǎo)致磁盤 IO 100% 占滿,服務(wù)器進(jìn)程阻塞(假死),查詢超時(shí)、連接斷開,甚至數(shù)據(jù)庫服務(wù)卡頓。
  • OOM 觸發(fā)條件(極少見):僅當(dāng)服務(wù)器內(nèi)存極?。ㄈ?4GB 以下)且臨時(shí)磁盤空間不足時(shí),才會因內(nèi)存 / 磁盤資源耗盡觸發(fā) OOM。

2. 客戶端:未開流式讀取必觸發(fā) OOM,開流式則無風(fēng)險(xiǎn)

  • 緩沖讀?。J(rèn)):如 JDBC 默認(rèn)配置、Navicat/DBeaver 等 GUI 工具,會一次性接收服務(wù)器推送的全量 2000 萬條數(shù)據(jù),數(shù)據(jù)量遠(yuǎn)超客戶端進(jìn)程 / JVM 內(nèi)存上限(如 JVM 堆內(nèi)存僅 8GB),直接觸發(fā) OOM(內(nèi)存溢出)。
  • 流式讀?。@式配置):如 mysql 命令行(默認(rèn)開啟)、JDBC 手動配置流式查詢,會逐批 / 逐行接收數(shù)據(jù),處理完一批釋放一批內(nèi)存,內(nèi)存占用恒定(僅幾十 KB~ 幾 MB),不會 OOM。

三、分維度解決方案(針對性解決服務(wù)器 / 客戶端問題)

1. 服務(wù)器端:解決 IO 假死 / 超時(shí)(唯一根本方案:拆分查詢)

核心邏輯:將 2000 萬條數(shù)據(jù)拆分為小批次(如每批 1 萬條),讓服務(wù)器每次僅處理少量數(shù)據(jù),避免全量數(shù)據(jù)觸發(fā)大量磁盤 IO。

# Shell腳本分批次查詢(按自增主鍵拆分,通用最優(yōu)方案)
#!/bin/bash
# 配置MySQL連接信息
MYSQL_USER="root"
MYSQL_PWD="你的密碼"
MYSQL_DB="目標(biāo)數(shù)據(jù)庫"
TABLE_NAME="目標(biāo)表"
RESULT_FILE="query_result.txt"

# 配置分批參數(shù):每批1萬條,總數(shù)據(jù)2000萬條
start_id=1
batch_size=10000
total_data=20000000

# 循環(huán)分批次查詢
while [ $start_id -le $total_data ]; do
  end_id=$((start_id + batch_size - 1))
  # 小批次查詢:服務(wù)器僅加載1萬條數(shù)據(jù),無大量臨時(shí)磁盤IO
  mysql -u${MYSQL_USER} -p${MYSQL_PWD} -D${MYSQL_DB} -N -s -e \
    "SELECT * FROM ${TABLE_NAME} WHERE id BETWEEN ${start_id} AND ${end_id};" >> ${RESULT_FILE}
  
  # 打印進(jìn)度(可選)
  echo "已查詢:id ${start_id} ~ ${end_id},進(jìn)度:$((start_id*100/total_data))%"
  
  # 更新起始ID,休眠0.2秒降低服務(wù)器壓力
  start_id=$((end_id + 1))
  sleep 0.2
done

echo "2000萬條數(shù)據(jù)查詢完成,結(jié)果已寫入${RESULT_FILE}"

適配無連續(xù)主鍵場景:若無自增 ID,可按時(shí)間字段拆分(如按創(chuàng)建時(shí)間分天 / 小時(shí)查詢):

-- 示例:按create_time分批次查詢(每批1小時(shí)數(shù)據(jù))
SELECT * FROM big_table WHERE create_time BETWEEN '2026-01-01 00:00:00' AND '2026-01-01 01:00:00';

2. 客戶端:解決 OOM(強(qiáng)制開啟流式讀?。?/strong>

不同客戶端的流式讀取配置方式:

表格

客戶端類型流式讀取配置方法
mysql 命令行默認(rèn)開啟無緩沖查詢,無需額外配置(天然不會 OOM)
JDBC(Java)禁用緩沖,設(shè)置流式讀取參數(shù):java<br>Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);<br>stmt.setFetchSize(Integer.MIN_VALUE); // 核心參數(shù)<br>ResultSet rs = stmt.executeQuery("SELECT * FROM big_table");<br>while (rs.next()) { 逐行處理數(shù)據(jù) }<br>
Navicat/DBeaver開啟「分批讀取」:Navicat→工具→選項(xiàng)→高級→設(shè)置「每次獲取行數(shù) = 1000」;DBeaver→連接配置→結(jié)果集→「分批獲取行數(shù)」

3. 服務(wù)器端兜底優(yōu)化(緩解 IO 壓力,非根本方案)

調(diào)整 MySQL 配置參數(shù),減少臨時(shí)磁盤 IO 開銷,避免服務(wù)器假死加?。?/p>

# my.cnf / my.ini 配置
[mysqld]
# 臨時(shí)文件目錄指向高速磁盤(如SSD),降低IO耗時(shí)
tmpdir = /data/mysql_tmp 
# 內(nèi)存臨時(shí)表上限,超出則寫入磁盤(不宜過大,避免占用過多內(nèi)存)
tmp_table_size = 64M     
max_heap_table_size = 64M
# 排序/讀取緩沖區(qū)大小,避免單查詢占用過多內(nèi)存
sort_buffer_size = 1M    
read_buffer_size = 1M    
# 關(guān)閉不必要的預(yù)讀,減少磁盤IO
innodb_read_ahead_threshold = 0
# 限制單查詢的并行度,避免搶占資源
innodb_thread_concurrency = 8

四、關(guān)鍵注意事項(xiàng)(避坑點(diǎn))

  • 流式讀取僅保護(hù)客戶端:客戶端開啟流式讀取只能避免自身 OOM,無法解決服務(wù)器端 IO 假死,必須配合分批次查詢;
  • LIMIT + OFFSET 慎用:OFFSET 越大,服務(wù)器仍需掃描更多數(shù)據(jù)(如 OFFSET 100 萬會先掃描 100 萬條再跳過),僅適合中小批次(<10 萬條);
  • 避免排序 / 聚合操作:帶 ORDER BY/GROUP BY 的查詢會讓服務(wù)器先加載全量數(shù)據(jù)排序,即使分批次也會觸發(fā)大量 IO,需優(yōu)先拆分后再在客戶端聚合;
  • 監(jiān)控服務(wù)器資源:查詢期間監(jiān)控服務(wù)器磁盤 IO(iostat)、內(nèi)存(free)、MySQL 進(jìn)程狀態(tài)(show processlist),避免資源耗盡。

五、最終核心結(jié)論

異常本質(zhì)

  • 服務(wù)器端:2000 萬條數(shù)據(jù)查詢→大量臨時(shí)磁盤 IO→IO 打滿→進(jìn)程假死 / 超時(shí)(極少 OOM);
  • 客戶端:未開流式讀取→一次性緩存全量數(shù)據(jù)→OOM(開流式則無風(fēng)險(xiǎn))。

核心解決方案

  • 服務(wù)器端:按主鍵 / 時(shí)間分批次查詢(每批 1 萬條),從根源減少磁盤 IO;
  • 客戶端:強(qiáng)制開啟流式 / 無緩沖讀取,避免 OOM;
  • 輔助優(yōu)化:調(diào)整 MySQL 參數(shù),緩解服務(wù)器 IO 壓力。

關(guān)鍵原則:MySQL 不適合一次性處理超大結(jié)果集,必須通過「分批次查詢 + 客戶端流式讀取」組合方案,才能避免服務(wù)器假死和客戶端 OOM。

到此這篇關(guān)于MySQL查詢2000w超大數(shù)據(jù)的解決方法的文章就介紹到這了,更多相關(guān)MySQL查詢數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL中WITH?AS語句的使用方法舉例

    MySQL中WITH?AS語句的使用方法舉例

    在MySQL中WITH AS語法用于創(chuàng)建一個(gè)臨時(shí)的命名查詢(也稱為子查詢),這些子查詢可以在后續(xù)的查詢中引用,從而簡化查詢語句的編寫,這篇文章主要給大家介紹了關(guān)于MySQL中WITH?AS語句的使用方法,需要的朋友可以參考下
    2024-06-06
  • Mysql觸發(fā)器在PHP項(xiàng)目中用來做信息備份、恢復(fù)和清空

    Mysql觸發(fā)器在PHP項(xiàng)目中用來做信息備份、恢復(fù)和清空

    這篇文章主要介紹了Mysql觸發(fā)器在PHP項(xiàng)目中用來做信息備份、恢復(fù)和清空的相關(guān)資料,需要的朋友可以參考下
    2017-11-11
  • MySQL性能監(jiān)控與安全管理的完整指南

    MySQL性能監(jiān)控與安全管理的完整指南

    MySQL 的性能監(jiān)控和安全管控是數(shù)據(jù)庫運(yùn)維的核心環(huán)節(jié),本文將深入探討 MySQL 的性能監(jiān)控工具、安全審計(jì)功能以及精細(xì)化的權(quán)限管理體系,幫助您構(gòu)建高性能且安全可靠的數(shù)據(jù)庫環(huán)境,需要的朋友可以參考下
    2025-10-10
  • mysql數(shù)據(jù)庫找不到表的問題及解決

    mysql數(shù)據(jù)庫找不到表的問題及解決

    這篇文章主要介紹了mysql數(shù)據(jù)庫找不到表的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • mysql-5.7.21-winx64免安裝版安裝--Windows 教程詳解

    mysql-5.7.21-winx64免安裝版安裝--Windows 教程詳解

    這篇文章主要介紹了mysql-5.7.21-winx64免安裝版安裝--Windows 教程詳解,非常不錯,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • Mysql LONGBLOB 類型存儲二進(jìn)制數(shù)據(jù) (修改+調(diào)試+整理)

    Mysql LONGBLOB 類型存儲二進(jìn)制數(shù)據(jù) (修改+調(diào)試+整理)

    代碼來自網(wǎng)絡(luò),我學(xué)習(xí)整理了一下,測試通過,下面的參數(shù)需要設(shè)置為你自己的
    2009-07-07
  • MySQL表字段時(shí)間設(shè)置默認(rèn)值

    MySQL表字段時(shí)間設(shè)置默認(rèn)值

    很多人可能會把日期類型的字段的類型設(shè)置為 date或者 datetime,但是這些不是當(dāng)前時(shí)間,那么如何把字段時(shí)間設(shè)置成當(dāng)前時(shí)間,本文就具體來介紹一下
    2021-05-05
  • MySQL數(shù)據(jù)連接查詢和子查詢操作過程

    MySQL數(shù)據(jù)連接查詢和子查詢操作過程

    本文詳細(xì)介紹了MySQL中數(shù)據(jù)連接查詢和子查詢的操作,包括準(zhǔn)備數(shù)據(jù)、查詢語法及解釋、數(shù)據(jù)連接查詢、子查詢、集合運(yùn)算查詢等內(nèi)容,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • MySQL命令行刪除表中的一個(gè)字段

    MySQL命令行刪除表中的一個(gè)字段

    本文介紹在MySQL數(shù)據(jù)庫中,如何根據(jù)字段名來刪除表中的一個(gè)字段,需要的朋友可以參考下
    2016-04-04
  • MySQL唯一索引與邏輯刪除沖突的解決方案匯總

    MySQL唯一索引與邏輯刪除沖突的解決方案匯總

    這篇文章主要介紹了在業(yè)務(wù)系統(tǒng)中使用邏輯刪除時(shí),如何處理唯一索引與邏輯刪除沖突的問題,文章介紹了多種解決方案,包括將刪除標(biāo)識設(shè)置為NULL、使用時(shí)間戳、新增刪除唯一標(biāo)識字段、虛擬生成列、物理刪除加歷史表以及引入外部緩存,需要的朋友可以參考下
    2025-11-11

最新評論

城口县| 五华县| 江安县| 茌平县| 云林县| 昌宁县| 临高县| 英德市| 普陀区| 防城港市| 禹城市| 大同县| 从化市| 同德县| 武乡县| 上栗县| 石棉县| 水城县| 武鸣县| 姚安县| 咸阳市| 长宁县| 山东省| 永春县| 北流市| 望奎县| 远安县| 衡阳市| 葫芦岛市| 舒兰市| 宕昌县| 崇左市| 九台市| 犍为县| 黄梅县| 行唐县| 通山县| 木里| 蒙自县| 临猗县| 宁安市|