以前總是說批量插入和更新的效率比非批量的要高,但是到底高多少,沒有評估過,今天我就具體的測試下 (1)三種插入操作的方法 1.1 利用for迴圈的批量插入
樣本xml
<insert id="insertUser"> insert into test_user (u_name,create_date) value (#{userName},SYSDATE()) </insert>
範例程式碼:
for (int i = 1; i <= num; i++) { User user = new User(); user.setUserName("a" + i); user.setCreateDate(new Date()); userDao.insertUser(user);}
1.2 採用jdbc
範例程式碼:
Connection conn; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://192.168.0.200:3306/xxx", "root", "root"); conn.setAutoCommit(false); String sql = "insert into test_user (u_name,create_date) value (?,SYSDATE())"; PreparedStatement prest = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); conn.setAutoCommit(false); for (int i = 1; i <= 100; i++) { prest.setString(1, "a" + i); prest.addBatch(); } prest.executeBatch(); conn.commit(); conn.close(); } catch (Exception ex) { ex.printStackTrace(); }
1.3 採用mybatis的批量插入方法
其實也是根據一個list 拼接成一個sql
樣本xml
<insert id="batchInsertList"> insert into test_user(u_name,create_date) values <foreach item="item" index="index" collection="userList" separator=","> (#{item.userName},SYSDATE()) </foreach> </insert>
範例程式碼
List<User> userList = new ArrayList<User>(); for (int i = 1; i <= num; i++) { User user = new User(); user.setUserName("a" + i); user.setCreateDate(new Date()); userList.add(user); } userDao.batchInsertList(userList);
資料量分別是10,100,300,1000,5000條資料
數量層級:10
批量插入耗時:141
非批量插入耗時:93
jdbc批量插入耗時:195
數量層級:100
批量插入耗時:164
非批量插入耗時:970
jdbc批量插入耗時:718
數量層級:300
批量插入耗時:355
非批量插入耗時:3030
jdbc批量插入耗時:1997
數量層級:500
批量插入耗時:258
非批量插入耗時:5355
jdbc批量插入耗時:2974
數量層級:1000
批量插入耗時:422
非批量插入耗時:8787
jdbc批量插入耗時:6440
數量層級:5000
批量插入耗時:870
非批量插入耗時:43498
jdbc批量插入耗時:30368
總體看來,效率排序
mybatis批量插入 > jdbc批量插入 > 迴圈調用insert語句 (2)三種批次更新的方法 2.1 利用for迴圈批次更新
樣本xml
<update id="updateUser"> update test_user set test_user.u_name = (#{updateUserName}) where test_user.u_name = (#{userName}) </update>
範例程式碼
for (int i = 1; i <= num; i++) { User user = new User(); user.setUserName("a" + i); user.setUpdateUserName("b" + i); userDao.updateUser(user); }
2.2 jdbc 批次更新
範例程式碼
Connection conn; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://192.168.0.200:3306/xxx", "root", "root"); conn.setAutoCommit(false); // 儲存當前自動認可模式 boolean autoCommit = conn.getAutoCommit(); // 關閉自動認可 conn.setAutoCommit(false); Statement stmt =conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); for (int i = 1; i <= num; i++) { stmt.addBatch("update test_user set test_user.u_name = ('d"+i+"') where test_user.u_name = ('c"+i+"')"); } stmt.executeBatch(); conn.commit(); conn.close(); } catch (Exception ex) { ex.printStackTrace(); }
2.3 mybatis 批次更新
其實是利用了mysql的批次更新的文法
case when的文法
詳見 【case when 文法】
樣本xml
<update id="batchUpdateList"> update test_user <trim prefix="set" suffixOverrides=","> <trim prefix="u_name =case" suffix="end,"> <foreach item="item" collection="userList"> when test_user.u_name = (#{item.userName}) then #{item.updateUserName} </foreach> </trim> </trim> where <foreach item="item" collection="userList" separator="or"> (test_user.u_name = (#{item.userName})) </foreach> </update>
範例程式碼
for (int i = 1; i <= num; i++) { User user = new User(); user.setUserName("a" + i); user.setUpdateUserName("b" + i); userList.add(user); } userDao.batchUpdateList(userList);
資料量分別是10,100,300,1000,5000條資料
資料量:10
批次更新耗時:279
非批次更新耗時:1522
jdbc批次更新耗時:255
資料量:100
批次更新耗時:720
非批次更新耗時:3391
jdbc批次更新耗時:1912
資料量:300
批次更新耗時:987
非批次更新耗時:9827
jdbc批次更新耗時:7616
資料量:500
批次更新耗時:1649
非批次更新耗時:16253
jdbc批次更新耗時:10475
資料量:1000
批次更新耗時:2552
非批次更新耗時:33048
jdbc批次更新耗時:20793
資料量:5000
批次更新耗時:19066
非批次更新耗時:239127
jdbc批次更新耗時:103273
綜上分析,效率排比如下
mybatis批次更新 > jdbc批次更新 > 迴圈調用update語句