JDBC實現往MySQL插入百萬級資料

2021-09-07 14:52:04 字數 4107 閱讀 9924

from:

想往某個表中插入幾百萬條資料做下測試,

原先的想法,直接寫個迴圈10w次隨便插入點資料試試吧,好吧,我真的很天真....

drop

procedure

ifexists proc_initdata;--

如果存在此儲存過程則刪掉

delimiter $

create

procedure

proc_initdata()

begin

declare i int

default1;

while i<=

100000

do

insert

into

text

values(i,concat('

姓名',i),'

*********');

set i = i+1;

endwhile

;end

$call proc_initdata();

執行call proc_initdata()後,本來想想,再慢10w條資料頂多30分鐘能搞定吧,結果我打了2把lol後,回頭一看,還在執行,此時心裡是徹底懵逼的....待我打完第三把結束後,終於執行完了,這種方法若是讓我等上幾百萬條資料,是不是早上去上班,下午下班回來還沒結束呢?10w條資料,有圖有真相

後面查了一下,使用jdbc批量操作往資料庫插入100w+的資料貌似也挺快的,

先來說說jdbc往資料庫中普通插入方式,簡單的**大致如下,迴圈了1000條,中間加點隨機的數值,畢竟自己要拿資料測試,資料全都一樣也不好區分

private string url = "jdbc:mysql://localhost:3306/test01";

private string user = "root";

private string password = "123456";

@test

public

void

test()

long endtime =system.currenttimemillis();

system.out.println("ok,用時:" + (endtime -starttime));

} catch

(exception e)

finally

catch

(sqlexception e)

}if(conn!=null

) catch

(sqlexception e) }}

}

輸出結果:ok,用時:738199,單位毫秒,也就是說這種方式與直接資料庫中迴圈是差不多的。

那麼低版本的驅動包是否對100w+資料插入就無力了呢?實際還有另外一種方式,效率相比來說還是可以接受的。

先將命令的提交方式設為false,即手動提交conn.setautocommit(false);最後在所有命令執行完之後再提交事務conn.commit();

private string url = "jdbc:mysql://localhost:3306/test01";

private string user = "root";

private string password = "123456";

@test

public

void

test()

conn.commit();

long endtime =system.currenttimemillis();

system.out.println("ok,用時:" + (endtime -starttime));

} catch

(exception e)

finally

catch

(sqlexception e)

}if(conn!=null

) catch

(sqlexception e) }}

}

以上**插入10w條資料,輸出結果:ok,用時:18086,也就十八秒左右的時間,理論上100w也就是3分鐘這樣,勉強還可以接受。

接下來就是批量處理了,注意,一定要5.1.13以上版本的驅動包。

private string url = "jdbc:mysql://localhost:3306/test01?rewritebatchedstatements=true";

private string user = "root";

private string password = "123456";

@test

public

void

test()

pstm.executebatch();

long endtime =system.currenttimemillis();

system.out.println("ok,用時:" + (endtime -starttime));

} catch

(exception e)

finally

catch

(sqlexception e)

}if(conn!=null

) catch

(sqlexception e) }}

}

10w輸出結果:ok,用時:3386,才3秒鐘.

然後我就想,要是批量操作+事務提交呢?會不會有神器的效果?

private string url = "jdbc:mysql://localhost:3306/test01?rewritebatchedstatements=true";

private string user = "root";

private string password = "123456";

@test

public

void

test()

pstm.executebatch();

conn.commit();

long endtime =system.currenttimemillis();

system.out.println("ok,用時:" + (endtime -starttime));

} catch

(exception e)

finally

catch

(sqlexception e)

}if(conn!=null

) catch

(sqlexception e) }}

}

以下是100w資料輸出對比:(5.1.17版本mysql驅動包下測試,交替兩種方式下的資料測試結果對比)

批量操作(10w)

批量操作+事務提交(10w)

批量操作(100w)

批量錯作+事務提交(100w)

ok,用時:3901

ok,用時:3343

ok,用時:44242

ok,用時:39798

ok,用時:4142

ok,用時:2949

ok,用時:44248

ok,用時:39959

ok,用時:3664

ok,用時:2689

ok,用時:44389

ok,用時:39367

可見有一定的效率提公升,但是並不是太明顯,當然因為資料差不算太大,也有可能存在偶然因數,畢竟每項只測3次。

網上還有人說使用預編譯+批量操作的方式能夠提高效率更明顯,但是本人親測,效率不高反降,可能跟測試的資料有關吧。

預編譯的寫法,只需在jdbc的連線url中將寫入useserverprepstmts=true即可,

如:

private string url = "jdbc:mysql://localhost:3306/test01?useserverprepstmts=true&rewritebatchedstatements=true"

好了,先到這裡...

往MySQL中插入資料

1 使用asp.net畫出如下介面 2 圖一的 如下 using mysql.data.mysqlclient using system using system.collections.generic using system.linq using system.web using system....

python 往MySQL批量插入資料

在工作用有時候需要批量造測試資料 手工造太麻煩了,可以通過python批量插入表資料 批量插入sql語句 import pymysql,string,random,time defconnet mysql try db pymysql.connect host 192.168.31.103 user...

JDBC往mysql裡存入中文的問題

之前出現過這樣的問題,後來處理完就忘記了,這次記錄以下,除了將資料庫的編碼格式設定為utf 8之外 還需要將dao層連線資料庫的url設定為 jdbc mysql localhost 埠 資料庫名?characterencoding utf 8 再使用連線 connection drivermana...