mysql批量插入数据
review代码发现,同事mysql批量插入数据的实现方法是,用for循环遍历,将列表每个数据单次插入。相当于批量插入N条数据,进行了n次的数据库连接和插入操作。
底层有批量插入的方法,但是会有问题,所以已经停用,看下面实现是,取到一个数据库连接,来处理后面所有的插入操作。若这个列表ops所有的sql语句执行的数据库都是同一个的话,就没什么问题,若里面存在散库的情况,只要跟第一个不在同一个库的,都会执行失败。
public void insertBatch(List<OpBatchUpdate> ops) throws SQLException { if(ops != null && ops.size() != 0) { OpBatchUpdate firstOp = (OpBatchUpdate)ops.get(0); if(firstOp.bizName != null && firstOp.bizName.trim().length() != 0) { PreparedStatement ps = null; Connection conn = null; long begin = 0L; try { begin = this.sqlBegin(); conn = this.getConn('w', firstOp);//取第一个来监理数据库连接 Iterator i$ = ops.iterator(); while(i$.hasNext()) { OpBatchUpdate opb = (OpBatchUpdate)i$.next(); ps = conn.prepareStatement(opb.getSql()); opb.setParam(ps); ps.executeUpdate(); if(ps != null) { ps.close(); } } } finally { this.closeRSC((ResultSet)null, ps, conn); this.sqlEnd("excutebatch sql,", begin); } } else { throw new SQLException(" ----- the bizName of the first opbatchupdate object can\'t null -------------"); } } else { throw new SQLException(" ----- the opbatchupdate list can\'t null -------------"); } }
对同一个库的同一个表进行批量插入操作。有两种方法:
以表smily_test为例:
CREATE TABLE `smily_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
1. for循环,将数据一条条插入。
insert into smily_test (uid) values(1); insert into smily_test (uid) values(2); insert into smily_test (uid) values(3);
2. 单次批量插入。
insert into smily_test (uid) values(1),(2),(3);
通过profile分析(查看mysql语句运行时间)得知:
方法2比方法1的效率高。
+----------+------------+------------------------------------------------+ | Query_ID | Duration | Query | +----------+------------+------------------------------------------------+ | 5 | 0.00079800 | insert into smily_test (uid) values(1) | | 6 | 0.00081300 | insert into smily_test (uid) values(2) | | 7 | 0.00078700 | insert into smily_test (uid) values(3) | | 8 | 0.00083200 | insert into smily_test (uid) values(1),(2),(3) | +----------+------------+------------------------------------------------+
总结:
方法1:执行效率偏低,会进行多次数据库的连接,比较耗时。但是适用于散库、散表的情况。
若数据在不同的库,则只能进行多次数据库连接。
若列表数据要插入同1个库的不同的表中,则可以选择1次数据库连接,多次数据插入执行的方式。
方法2:执行时间短,只适用于对同一个库同一个表批量插入数据的情况。