首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 大批量 INSERT 效能優化:從逐條插入到批次合併,提速 100 倍

     編輯:MySQL 綜合教學

痛點:逐條 INSERT 極慢

// 反模式:循環逐條執行
for (int i = 0; i < list.size(); i++) {
  String sql = "INSERT INTO rddform ... VALUES (...)";
  stmt.executeUpdate(sql);  // 每條一次網路往返 + 事務提交
}
// 本地 ~20 行/秒,雲端 ~3 行/秒,2000 條需 1.5~10 分鐘

優化:單條 SQL 批次插入 (Multi-row INSERT)

// 優化:拼接單條 SQL,一次提交
StringBuilder sb = new StringBuilder("INSERT INTO rddform (cols) VALUES ");
for (int i = 0; i < list.size(); i++) {
  sb.append("(").append(vals).append(")");
  if (i < list.size()-1) sb.append(",");
}
stmt.executeUpdate(sb.toString());
// 本地/雲端均 **秒級完成**,提速 100x+

核心優化原理

  • 減少網路往返:1 次 RTT 替代 N 次
  • 減少解析/優化開銷:1 次解析替代 N 次
  • 減少事務提交/日誌刷盤:1 次提交替代 N 次 (若自動提交)
  • InnoDB 批次寫入:減少 undo/redo log 同步開銷

生產環境關鍵配置與限制

最佳實踐清單

  1. 分批提交:每批 500~5000 行,視行大小調整,防超 max_allowed_packet。
  2. 手動事務控制:SET autocommit=0; ... COMMIT; 而非自動提交。
  3. 參數化預處理:PreparedStatement.addBatch() 更安全、可復用執行計劃。
  4. 關閉非必要索引/外鍵:大量導入時暫時 DROP INDEX、SET FOREIGN_KEY_CHECKS=0,結束後重建。
  5. 主鍵順序插入:按主鍵遞增順序插入,減少頁分裂與碎片。
  6. 監控 Innodb_log_waits:若增長快,說明 redo log 刷盤跟不上,擴大 innodb_log_file_size 或 innodb_log_buffer_size。

對比圖表說明

文中圖片展示:逐條插入 (藍線) 隨資料量線性增長耗時;批次插入 (紅線) 呈對數級增長,2000 行從 90 秒降至 <1 秒。

遷移到 Load Data (極致速度)

LOAD DATA INFILE '/path/data.csv'
INTO TABLE rddform
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(col1, col2, ...);

繞過 SQL 層,直接由存儲引擎寫入,**再快 5-10 倍**,適合 TB 級導入。

結論:**拒絕循環 INSERT,擁抱批次合併與 Load Data**,資料導入不再是瓶頸。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數/限制預設值建議調整說明
max_allowed_packet4MB/1MB16MB~64MB單條 SQL 最大長度,批次大小受限於此
innodb_log_buffer_size8MB~64MB64MB~256MB大事務緩衝 redo log,避免頻繁刷盤
bulk_insert_buffer_size8MB64MB~128MBMyISAM 專用,InnoDB 無效
SQL 長度限制max_allowed_packet分批提交超長 SQL 需拆分多批次