我的投機取巧竟然忘了mysql還有一個最大值的限制

2021-12-28 IT大咖說

前言:項目開發中沒有考慮到數據量的問題,在運行階段突然有一天報Packet for query is too large錯誤。這裡先說個例子,比如有10條數據需要插入到資料庫。我們通常的實現是:

List<Object> list = new ArrayList<>();
for(int i=0;i<list .size());i++){
insert(list.get(i)))
}
// sql語句就是10個insert into table values(?,?)

而我不想在循環list了,我想一條sql搞定,因為mysql不是可以insert into table values(?,?),(?,?),(?,?)這樣寫嗎。我在mybatis中使用foreach就可以實現了。

List<Object> list = new ArrayList<>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("list",list);
insert(map);

如下mybatis中foreach的寫法,collection中的list就是我map中的list。

foreach寫法

但是這裡有個bug,我沒有考慮到mysql中有一個大小限制,即max_allowed_packet。

項目這是運行後,發現有一個大帳戶,插入一直報錯,查看日誌發現如圖錯誤。

報錯信息

Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large

意思就是我超過Packet的最大限制了。也就是我上面提到的max_allowed_packet這個參數。查看這個參數:

查看max_allowed_packet

1048576位元組=1M,也就是mysql默認的。那麼問題來了,我是修改這個參數,還是另尋其它解決辦法。我選擇了最後一個。原因:

因為線上資料庫不允許重啟,網上百度說設置這個參數後,重啟才能生效。

這個值設置多大合適不知道,我這次設置為2M,下次可能出現個3M的情況。

不知道大家有沒有實現過採用文件的形式插入數據,即load方式。

我的實現方式,先把數據寫入到csv文件裡,我通過load把這個文件的數據插入到資料庫。

load方式

這裡呢一定要注意編碼問題,不然會亂碼還有數據之間是採用什麼分隔的,如csv就是使用「,」分隔。

csv文件導入的sql:

LOAD DATA LOCAL INFILE 'E:/1111.csv' ignore into table qwe1231 CHARACTER SET utf8
fields terminated by ',' enclosed by "" IGNORE 1 LINES

總結:

在查詢大數據量和插入大數據量數據時,一定要注意max_allowed_packet的值問題,這裡我們可以採用分頁查詢,分頁插入。

load方式在處理大數據量問題還是比較容易的,而且速度很快。

來源:

https://www.toutiao.com/i6779085316209771019/

「IT大咖說」歡迎廣大技術人員投稿,投稿郵箱:aliang@itdks.com


 IT大咖說  |  關於版權 

由「IT大咖說(ID:itdakashuo)」原創的文章,轉載時請註明作者、出處及微信公眾號。投稿、約稿、轉載請加微信:ITDKS10(備註:投稿),茉莉小姐姐會及時與您聯繫!

感謝您對IT大咖說的熱心支持!

相關焦點

  • 被逼無奈學了幾個mysql命令,竟然有大用.
    這是一個欲哭無淚得故事,故事從開始到結束花了我整整2個小時。現在開始進入這個小故事,請備好垃圾桶。下面這張圖,就是我的網站前兩天的狀態。image.png這個是我的前端刷題網站,後臺數據是mysql,前天深夜我玩著玩著突然給玩壞了,數據連結失敗,navicat也不好使了。所以就有了上面那副圖,你也絕對想不到我是怎樣解決這個問題的。
  • MYSQL 8 一個實例打開的表被那些參數和資源限制 分析
    首先安裝sysbench 並通過下面的命令來對mysql test 資料庫產生 10000萬張表。在產生這些表後,就需要通過sysbench對其進行壓測,在壓測的過程中發現報錯max_prepared_stmt_count 提出測試的過程中,測試中的無法進行線程的初始化。
  • MYSQL 入門全套
    使用mysql必須具備一下條件1、下載地址:http://dev.mysql.com/downloads/mysql/2、安裝註:以上兩個連結有完整的安裝方式,擼主也是參考他的安裝的,安裝完以後mysql.server start啟動mysql服務mysql操作一、連接資料庫mysql
  • mysql資料庫select查詢語句
    select的相關語句在mysql中用的非常多,介紹一下。語句的介紹1 select * from 表名;*(代表表中的所有欄位)2 select distinct 欄位名 from 表名 ; distinct 去掉重複欄位3 select * from 表名 where 條件 ;where 添加查詢的限制條件
  • MySQL MEMORY 引擎及性能比對
    在負載增加時限制了可擴展性,特別是寫操作。儘管內存表在內存中處理,在繁忙的服務網上,並不一定比InnoDB表更快,如一般查詢或者讀寫場景。特別是,多個會話執行update操作會造成性能低下。根據不同的SQL查詢,需要創建內存表的默認hash索引(基於唯一鍵的單個值查詢),或者B-tree索引(等值查詢、不等值查詢或者範圍查詢)。
  • 乾貨| 如何在MySQL中存儲貨幣?
    DECIMAL是一種高精度的定點數據類型,在MySQL中它還有1個同義詞:NUMERIC,這兩個數據類型在 MySQL 中被視為相同的類型。目前業內大多都是採用這種數據類型來保存財務數據等對精度要求非常高的數據。不過凡事無絕對,你也可以把財務數據使用BIGINT的數據類型做存儲。
  • MySQL 8.0.0 發布
    Information Schema 現在以數據字典表的一個視圖出現。原則上可以完全不需要 MyISAM 數據表類型了,所有的系統表都可以放到 InnoDB 之中。SQL 角色角色是一系列權限的集合。可以創建角色,給某個用戶授予和去除角色。這對於權限管理很方便。
  • MySQL注入繞過新思路
    字符串處理先看看mysql對於字符串的處理,可以看到一個字符串是等於0的。再看看將字符串和MySQL支持的最大值加起來的結果。可以看到,字符串返回的是DOUBLE數字,而將一個大值和一個DOUBLE值相加時,將會返回IEEE標準的DOUBLE精確值。這時候我們可以通過或操作獲取到最大的無符號BIGINT值。
  • MySQL 資料庫「十宗罪」(十大經典錯誤案例)
    今天給大家說說《資料庫中十大經典錯誤案例》老牛我在剛開始學習資料庫的時候,沒少走彎路。經常會遇到各種稀奇古怪的 error 信息,遇到報錯會很慌張,急需一個解決問題的辦法。跟無頭蒼蠅一樣,會不加思索地把錯誤粘到百度上,希望趕緊查找一下有沒有好的處理問題的方法。我想這個應該是剛從事資料庫的小白,都會遇到窘境。
  • MySQL8.0新特性
    我感覺這樣做唯一的好處就是使語句的語義更加清晰了一點。大家可以自行嘗試一下。下面示例演示基礎的概念,首先我這裡創建了一個資料庫表數據如下圖:簡單用一句話來說就是mysql8.0中重新重構了這個數據字典,主要變化是刪除了之前版本中存儲在元數據中的資料庫信息,比如 關於表的 .frm .opt 還有關於觸發器的一些文件等..我們可以在mysql8.0之前的版本中的 lib目錄看一下。
  • 掌握後可為孩子收藏的MySQL入門全套
    使用mysql必須具備一下條件1、下載地址:http://dev.mysql.com/downloads/mysql/2、安裝註:以上兩個連結有完整的安裝方式,擼主也是參考他的安裝的,安裝完以後mysql.server start啟動mysql服務mysql操作一、連接資料庫mysql
  • MySQL5.7中如何使用開窗函數
    關注我,獲的更多分享。>背景準備實驗環境準備建表語句初始化數據分組排序分組統計分組求最大值但是我們目前還有很多人在使用5.7版本。那麼在5.7版本中,如何實現開窗函數的功能呢?把這個作為一個新列查詢出出來。基於步驟1的結果集中的新列,和員工的工資列做減法得到差值。
  • 了解資料庫類型及MySQL資料庫常用命令行
    2、資料庫的分類(1) 關係型資料庫(sql資料庫):中型:mysql(埠號3306)、sql server大型:Oracle(埠號1521)(2) 非關係型資料庫(no-sql資料庫)>MongoDB、Redis3、mysql軟體:Sql yog:資料庫客戶端工具(圖形用戶界面工具)方便操作資料庫。
  • ProxySQL + MySQL MGR讀寫分離架構的Sysbench只讀壓測報告
    在大量並發讀請求、讀多寫少的業務場景下,本文利用 Sysbench 性能測試工具,調研基於【負載均衡 + ProxySQL Cluster + MySQL MGR 的讀寫分離架構】能否有效利用橫向擴展的 MySQL 實例的讀能力,並最終提高應用系統 QPS。
  • MySQL十大經典錯誤案例,你遇到過幾個?
    MySQL 資料庫參數文件裡面,對應的 max_connections 這個參數值是不是設置的太小了,導致客戶端連接數超過了資料庫所承受的最大值。2、其次可以限制 Innodb 的並發處理數量,如果 innodb_thread_concurrency = 0(這種代表不受限制) 可以先改成 16 或是 64 看伺服器壓力。如果非常大,可以先改的小一點讓伺服器的壓力下來之後,然後再慢慢增大,根據自己的業務而定。個人建議可以先調整為 16 即可。
  • 由一條create語句的問題對比mysql和oracle中的date差別 (r7筆記第26天)
    5.5這個時候手頭有一套虛擬機測試環境,立馬實驗了一下,發現在5.6中竟然沒有任何問題。得到的信息如下Query OK, 0 rows affected (0.13 sec)所以這個問題引起了我的注意。我做了下面幾個測試,首先current_timestamp肯定是可用的。看看時間的情況。
  • 職場正道:與其投機取巧,不如謹守本分
    這一番話,叫郝建心花怒放,原本還擔心轉正的事情,現在竟然不光轉正沒問題,還有升職的機會,他也順勢恭維馬科長,預祝她早日升任處長。他(她)們互相投其所好,相互合作,利益共享,實現雙贏。沒想到,杜局長早已了解馬科長的這一套拍馬屁功夫,專程過來揭穿她。對於郝建的表現,杜局長也提前熟悉,認為他是一個業務能力不錯的好同志,應該給予轉正。
  • MySQL 資料庫基本命令匯總整理,需要的趕緊學起來
    (),mysql_query())$conn = mysql_connect(「localhost」,」username」,」password」) ordie ( 「could not connect to localhost」);1.
  • MySQL 注入攻擊與防禦
    該變量用於限制數據的導入和導出操作,例如SELECT … INTO OUTFILE語句和LOAD_FILE()如果secure_file_priv變量為空那麼直接可以使用函數,如果為null是不能使用但在mysql的5.5.53之前的版本是默認為空,之後的版本為null,所有是將這個功能禁掉了
  • MySQL資料庫「十宗罪」(十大經典錯誤案例)
    解決問題的思路:1、首先先要考慮在我們 MySQL 資料庫參數文件裡面,對應的max_connections 這個參數值是不是設置的太小了,導致客戶端連接數超過了資料庫所承受的最大值。因為在資料庫中,mysql資料庫中user表記錄著我們用戶的信息。解決方法:啟動 MySQL 資料庫的過程中,可以這樣執行: