MySQL數(shù)據(jù)庫(kù)10秒內(nèi)插入百萬(wàn)條數(shù)據(jù)的實(shí)現(xiàn)
首先我們思考一個(gè)問題:
要插入如此龐大的數(shù)據(jù)到數(shù)據(jù)庫(kù),正常情況一定會(huì)頻繁地進(jìn)行訪問,什么樣的機(jī)器設(shè)備都吃不消。那么如何避免頻繁訪問數(shù)據(jù)庫(kù),能否做到一次訪問,再執(zhí)行呢?
Java其實(shí)已經(jīng)給了我們答案。
這里就要用到兩個(gè)關(guān)鍵對(duì)象:Statement、PrepareStatement
我們來看一下二者的特性:

要用到的BaseDao工具類 (jar包 / Maven依賴) (Maven依賴代碼附在文末)(封裝以便于使用)

注:(重點(diǎn))rewriteBatchedStatements=true,一次插入多條數(shù)據(jù),只插入一次??!
public class BaseDao { // 靜態(tài)工具類,用于創(chuàng)建數(shù)據(jù)庫(kù)連接對(duì)象和釋放資源,方便調(diào)用
// 導(dǎo)入驅(qū)動(dòng)jar包或添加Maven依賴(這里使用的是Maven,Maven依賴代碼附在文末)
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 獲取數(shù)據(jù)庫(kù)連接對(duì)象
public static Connection getConn() {
Connection conn = null;
try {
// rewriteBatchedStatements=true,一次插入多條數(shù)據(jù),只插入一次
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/million-test?rewriteBatchedStatements=true", "root", "qwerdf");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
// 釋放資源
public static void closeAll(AutoCloseable... autoCloseables) {
for (AutoCloseable autoCloseable : autoCloseables) {
if (autoCloseable != null) {
try {
autoCloseable.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
接下來上關(guān)鍵代碼及注釋:
/* 因?yàn)閿?shù)據(jù)庫(kù)的處理速度是非常驚人的 單次吞吐量很大 執(zhí)行效率極高
addBatch()把若干sql語(yǔ)句裝載到一起,然后一次送到數(shù)據(jù)庫(kù)執(zhí)行,執(zhí)行需要很短的時(shí)間
而preparedStatement.executeUpdate() 是一條一條發(fā)往數(shù)據(jù)庫(kù)執(zhí)行的 時(shí)間都消耗在數(shù)據(jù)庫(kù)連接的傳輸上面*/
public static void main(String[] args) {
long start = System.currentTimeMillis(); // 獲取系統(tǒng)當(dāng)前時(shí)間,方法開始執(zhí)行前記錄
Connection conn = BaseDao.getConn(); // 調(diào)用剛剛寫好的用于獲取連接數(shù)據(jù)庫(kù)對(duì)象的靜態(tài)工具類
String sql = "insert into mymilliontest values(null,?,?,?,NOW())"; // 要執(zhí)行的sql語(yǔ)句
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql); // 獲取PreparedStatement對(duì)象
// 不斷產(chǎn)生sql
for (int i = 0; i < 1000000; i++) {
ps.setString(1, Math.ceil(Math.random() * 1000000) + "");
ps.setString(2, Math.ceil(Math.random() * 1000000) + "");
ps.setString(3, UUID.randomUUID().toString()); // UUID該類用于隨機(jī)生成一串不會(huì)重復(fù)的字符串
ps.addBatch(); // 將一組參數(shù)添加到此 PreparedStatement 對(duì)象的批處理命令中。
}
int[] ints = ps.executeBatch();// 將一批命令提交給數(shù)據(jù)庫(kù)來執(zhí)行,如果全部命令執(zhí)行成功,則返回更新計(jì)數(shù)組成的數(shù)組。
// 如果數(shù)組長(zhǎng)度不為0,則說明sql語(yǔ)句成功執(zhí)行,即百萬(wàn)條數(shù)據(jù)添加成功!
if (ints.length > 0) {
System.out.println("已成功添加一百萬(wàn)條數(shù)據(jù)!!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
BaseDao.closeAll(conn, ps); // 調(diào)用剛剛寫好的靜態(tài)工具類釋放資源
}
long end = System.currentTimeMillis(); // 再次獲取系統(tǒng)時(shí)間
System.out.println("所用時(shí)長(zhǎng):" + (end - start) / 1000 + "秒"); // 兩個(gè)時(shí)間相減即為方法執(zhí)行所用時(shí)長(zhǎng)
}
最后我們運(yùn)行看一下效果:


嘿嘿,這里時(shí)長(zhǎng)超過了10秒,設(shè)備差點(diǎn)意思,希望理解哈~

<!--連接數(shù)據(jù)庫(kù)所用到的mysql-connector-java依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
PS : 添上線程后會(huì)更快,在后續(xù)的文章中會(huì)作示例。
到此這篇關(guān)于MySQL數(shù)據(jù)庫(kù)10秒內(nèi)插入百萬(wàn)條數(shù)據(jù)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL 插入百萬(wàn)條數(shù)據(jù) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一步步教你利用Mysql存儲(chǔ)過程造百萬(wàn)級(jí)數(shù)據(jù)
- MySQL 百萬(wàn)級(jí)數(shù)據(jù)的4種查詢優(yōu)化方式
- MySQL百萬(wàn)級(jí)數(shù)據(jù)量分頁(yè)查詢方法及其優(yōu)化建議
- MySQL百萬(wàn)級(jí)數(shù)據(jù)分頁(yè)查詢優(yōu)化方案
- java中JDBC實(shí)現(xiàn)往MySQL插入百萬(wàn)級(jí)數(shù)據(jù)的實(shí)例代碼
- MySQL單表百萬(wàn)數(shù)據(jù)記錄分頁(yè)性能優(yōu)化技巧
- MySQL使用MyFlash快速恢復(fù)誤刪除和修改的數(shù)據(jù)
- MySQL數(shù)據(jù)庫(kù)刪除數(shù)據(jù)后自增ID不連續(xù)的問題及解決
- MySQL BinLog如何恢復(fù)誤更新刪除數(shù)據(jù)
- 使用 SQL 快速刪除數(shù)百萬(wàn)行數(shù)據(jù)的實(shí)踐記錄
相關(guān)文章
MySQL字符串索引更合理的創(chuàng)建規(guī)則討論
這篇文章主要給大家介紹了關(guān)于MySQL字符串索引更合理的創(chuàng)建規(guī)則,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
MySQL 搭建雙主復(fù)制服務(wù)并通過 HAProxy 負(fù)載均衡的過程詳解
在數(shù)據(jù)庫(kù)管理中,數(shù)據(jù)的備份和同步是至關(guān)重要的環(huán)節(jié),而雙主復(fù)制(Dual Master Replication)作為一種高可用性和數(shù)據(jù)同步的解決方案,本文將介紹MySQL雙主復(fù)制的配置過程并通過 HAProxy 負(fù)載均衡,感興趣的朋友一起看看吧2024-03-03
Mysql連接join查詢?cè)碇R(shí)點(diǎn)
在本文里我們給大家整理了一篇關(guān)于Mysql連接join查詢?cè)碇R(shí)點(diǎn)文章,對(duì)此感興趣的朋友們可以學(xué)習(xí)下。2019-02-02
mysql use命令選擇數(shù)據(jù)庫(kù)詳解
這篇文章主要介紹了mysql 使用use命令選擇數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下2016-09-09
在JPA項(xiàng)目啟動(dòng)時(shí)如何新增MySQL字段
這篇文章主要介紹了在JPA項(xiàng)目啟動(dòng)時(shí)新增MySQL字段,本來用了JPA,直接實(shí)體類加參數(shù)就可以新增字段了,但是架不住垃圾項(xiàng)目在啟動(dòng)項(xiàng)目時(shí)會(huì)加載數(shù)據(jù)庫(kù)SQL文件去插入數(shù)據(jù),需要一些操作幫助修復(fù),需要的朋友可以參考下2024-06-06
關(guān)于Mysql8.0版本驅(qū)動(dòng)getTables返回所有庫(kù)的表問題淺析
這篇文章主要給大家介紹了關(guān)于Mysql 8.0版本驅(qū)動(dòng)getTables返回所有庫(kù)的表問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
MySQL中實(shí)現(xiàn)行列轉(zhuǎn)換的操作示例
在 MySQL 中進(jìn)行行列轉(zhuǎn)換(即,將某些列轉(zhuǎn)換為行或?qū)⒛承┬修D(zhuǎn)換為列)通常涉及使用條件邏輯和聚合函數(shù),本文給大家介紹了MySQL中實(shí)現(xiàn)行列轉(zhuǎn)換的操作示例,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-06-06

