mysql中批量插入數(shù)據(jù)(1萬、10萬、100萬、1000萬、1億級別)
硬件:windows7+8G內(nèi)存+i3-4170處理器+4核CPU
首先貼上數(shù)據(jù)庫的操作類BaseDao:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.lk.entity.TUser;
public class BaseDao {
private static ConfigManager cm = ConfigManager.getInstance();
private static String Driver = null;
private static String URL = null;
private static String USER = null;
private static String PWD = null;
private static Connection conn = null;
private static PreparedStatement psmt = null;
public ResultSet rs = null;
public int row = 0;
static {
Driver = cm.getString("DRIVER");
URL = cm.getString("URL");
USER = cm.getString("USER");
PWD = cm.getString("PWD");
try {
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
getConnection();
try {
conn.setAutoCommit(false);
psmt = conn.prepareStatement("");
} catch (SQLException e) {
e.printStackTrace();
}
}
private static Connection getConnection() {
try {
conn = DriverManager.getConnection(URL, USER, PWD);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 多條記錄插入操作
* flag是為了判斷是否是插入的最后一個記錄
*/
public boolean affectRowMore(String sql, List<TUser> list, long flag) {
try {
psmt = conn.prepareStatement(sql);
for (TUser tUser : list) {
psmt.setLong(1, tUser.getId());
psmt.setString(2, tUser.getName());
psmt.setInt(3, tUser.getSex());
psmt.setString(4, tUser.getPhone());
psmt.setString(5, tUser.getPassword());
// 添加執(zhí)行sql
psmt.addBatch();
}
// 執(zhí)行操作
int[] counts = psmt.executeBatch(); // 執(zhí)行Batch中的全部語句
conn.commit(); // 提交到數(shù)據(jù)庫
for (int i : counts) {
if (i == 0) {
conn.rollback();
}
}
closeAll(flag);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 多條記錄插入操作
*/
public boolean affectRowMore1(String sql, long flag) {
try {
psmt.addBatch(sql);
// 執(zhí)行操作
int[] counts = psmt.executeBatch(); // 執(zhí)行Batch中的全部語句
conn.commit(); // 提交到數(shù)據(jù)庫
for (int i : counts) {
if (i == 0) {
conn.rollback();
return false;
}
}
closeAll(flag);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
public void closeAll(long flag) {
try {
if (conn != null && flag == -1) {
// 在完成批量操作后恢復(fù)默認的自動提交方式,提高程序的可擴展性
conn.setAutoCommit(true);
conn.close();
}
if (psmt != null && flag == -1) {
psmt.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}方法一:
通過BaseDao中的affectRowMore方法進行插入,插入的速度如下所示:
* 一萬條數(shù)據(jù)(通過多條添加)
* 生成1萬條數(shù)據(jù)共花費978毫秒
* 生成10萬條數(shù)據(jù)共花費5826毫秒
* 生成100萬條數(shù)據(jù)共花費54929毫秒
* 生成1000萬條數(shù)據(jù)共花費548640毫秒
* 生成1億條數(shù)據(jù)(因為數(shù)字過大,沒有計算)
public void insertBenchMark() {
?? ??? ?long start = System.currentTimeMillis();
?? ??? ?List<TUser> list = new ArrayList<>();
?? ??? ?long row = 1;
?? ??? ?for (int j = 0; j < 1000; j++) {
?? ??? ??? ?for (int i = 0; i < 10000; i++) {
?? ??? ??? ??? ?String uuid = UUID.randomUUID().toString();
?? ??? ??? ??? ?String name = uuid.substring(0, 4);
?? ??? ??? ??? ?int sex = -1;
?? ??? ??? ??? ?if(Math.random() < 0.51) {
?? ??? ??? ??? ??? ?sex = 1;
?? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ?sex = 0;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?String phone = (String) RandomValue.getAddress().get("tel");
?? ??? ??? ??? ?list.add(new TUser(row,name, sex, phone, uuid));
?? ??? ??? ??? ?row++;
?? ??? ??? ?}
?? ??? ??? ?int flag = 1;
?? ??? ??? ?if(j==999) {
?? ??? ??? ??? ?flag = -1;
?? ??? ??? ?}
?? ??? ??? ?//封裝好的
?? ??? ??? ?boolean b = userDao.insertMore(list,flag);
?? ??? ??? ?if(!b) {
?? ??? ??? ??? ?System.out.println("出錯了----");
?? ??? ??? ??? ?System.exit(0);
?? ??? ??? ?}else {
?? ??? ??? ??? ?list.clear();
?? ??? ??? ?}
?? ??? ?}
?? ??? ?long end = System.currentTimeMillis();
?? ??? ?System.out.println("生成1000萬條數(shù)據(jù)共花費"+(end-start)+"毫秒");
?? ?}
public boolean insertMore(List<TUser> list,long flag) {
?? ??? ?String sql = "insert into tuser(id,name,sex,phone,password) values(?,?,?,?,?)";
?? ??? ?return affectRowMore(sql,list,flag);
?? ?}方法二:
通過BaseDao中的affectRowMore1方法進行數(shù)據(jù)的插入操作,插入的速度如下:
* 通過拼接語句實現(xiàn)多條添加
* 生成1萬條數(shù)據(jù)共花費225毫秒
* 生成10萬條數(shù)據(jù)共花費1586毫秒
* 生成100萬條數(shù)據(jù)共花費14017毫秒
* 生成1000萬條數(shù)據(jù)共花費152127毫秒
* 生成1億條數(shù)據(jù)(因為數(shù)字過大,沒有計算)
public void insertBenchMark1() {
?? ??? ?long start = System.currentTimeMillis();
?? ??? ?StringBuffer suffix = new StringBuffer();
?? ??? ?long row = 1;
?? ??? ?for (int j = 0; j < 1000; j++) {
?? ??? ??? ?for (int i = 0; i < 10000; i++) {
?? ??? ??? ??? ?String uuid = UUID.randomUUID().toString();
?? ??? ??? ??? ?String name = uuid.substring(0, 4);
?? ??? ??? ??? ?int sex = -1;
?? ??? ??? ??? ?if(Math.random() < 0.51) {
?? ??? ??? ??? ??? ?sex = 1;
?? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ?sex = 0;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?String phone = (String) RandomValue.getAddress().get("tel");
?? ??? ??? ??? ?suffix.append("(" + row + ",'" + name + "'," + sex + ",'" + phone + "','" + uuid + "'),");
?? ??? ??? ??? ?row++;
?? ??? ??? ?}
?? ??? ??? ?boolean b = userDao.insertMore1(suffix.substring(0, suffix.length()-1),j);
?? ??? ??? ?if(!b) {
?? ??? ??? ??? ?System.out.println("出錯了----");
?? ??? ??? ??? ?System.exit(0);
?? ??? ??? ?}else {
?? ??? ??? ??? ?// 清空上一次添加的數(shù)據(jù)
?? ??? ??? ??? ?suffix = new StringBuffer();
?? ??? ??? ?}
?? ??? ?}
?? ??? ?long end = System.currentTimeMillis();
?? ??? ?System.out.println("生成1000萬條數(shù)據(jù)共花費"+(end-start)+"毫秒");
?? ?}
public boolean insertMore1(String sql_suffix,long flag) {
?? ??? ?String sql_prefix = "insert into tuser(id,name,sex,phone,password) values ";
?? ??? ?return affectRowMore1(sql_prefix + sql_suffix,flag);
?? ?}總結(jié):
方法一和方法二很類同,唯一不同的是方法一采用的是“insert into tb (...) values (...);insert into tb (...) values (...);...”的方式執(zhí)行插入操作,方法二則是“insert into tb (...) values(...),(...)...;”的方式。
通過測試的對比,方法二比方法一快了近5倍。
到此這篇關(guān)于mysql中批量插入數(shù)據(jù)(1萬、10萬、100萬、1000萬、1億級別)的文章就介紹到這了,更多相關(guān)mysql 批量插入數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL8設(shè)置自動創(chuàng)建時間和自動更新時間的實現(xiàn)方法
在實際應(yīng)用中,我們時常會需要用到創(chuàng)建時間和更新時間這兩個字段,下面這篇文章主要給大家介紹了關(guān)于MySQL8設(shè)置自動創(chuàng)建時間和自動更新時間的實現(xiàn)方法,需要的朋友可以參考下2023-03-03
MySQL數(shù)據(jù)庫表的合并及分區(qū)方式
這篇文章主要介紹了MySQL數(shù)據(jù)庫表的合并及分區(qū)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
MySQL實現(xiàn)樹狀所有子節(jié)點查詢的方法
這篇文章主要介紹了MySQL實現(xiàn)樹狀所有子節(jié)點查詢的方法,涉及mysql節(jié)點查詢、存儲過程調(diào)用等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-06-06
MySQ登錄提示ERROR 1045 (28000)錯誤的解決方法
這篇文章主要為大家詳細介紹了MySQ登錄提示ERROR 1045 (28000)錯誤的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
Mysql 日期時間 DATE_FORMAT(date,format)
Mysql 日期時間 DATE_FORMAT(date,format) ,需要的朋友可以參考下。2010-12-12

