prepareStatementInsert()执行时间为:12797ms 对比分析: 采用prepareStatement的方式确实可以提高一点性能,因为减少了数据库引擎解析优化SQL语句的时间,但是由于现在的插入语句太简单,所以性能提升不明显。 四、批量插入:addBatch、executeBatch 代码: 1 Connection conn=source.getConnection(); 输出结果:2 conn.setAutoCommit(false); 3 Statement s=conn.createStatement(); 4 String sql=""; 5 long start=System.currentTimeMillis(); 6 for(int j=0;j<100;j++) 7 { 8 for(int i=0;i<1000;i++) 9 { 10 sql="insert into user(id,name) value('"+(i+1)+"','chenxinhan')"; 11 s.addBatch(sql); 12 } 13 s.executeBatch(); 14 conn.commit(); 15 s.clearBatch(); 16 } 17 s.close(); 18 conn.close(); 19 long end=System.currentTimeMillis(); 20 System.out.println("batchInsert()执行时间为:"+(end-start)+"ms"); batchInsert()执行时间为:13625ms 对比分析: 按道理,这种批处理的方式是要快些的,但是测试结果却不尽人意,有点不解,请高人拍砖。 五、批量插入:insert into tableName (x,xx,xxx) values(x,xx,xxx),(xx,xxx,xxxx)…, 代码: 1Connection conn=source.getConnection(); 输出结果:2 conn.setAutoCommit(false); 3 Statement s=conn.createStatement(); 4 StringBuilder sql=new StringBuilder(""); 5 long start=System.currentTimeMillis(); 6 for(int j=0;j<100;j++) 7 { 8 sql=new StringBuilder(""); 9 sql.append("insert into user(id,name) values "); 10 for(int i=0;i<1000;i++) 11 { 12 if(i==999) 13 sql.append("('").append(i+1).append("',").append("'cxh')"); 14 else 15 sql.append("('").append(i+1).append("',").append("'cxh'),"); 16 } 17 s.execute(sql.toString()); 18 conn.commit(); 19 } 20 s.close(); 21 conn.close(); 22 long end=System.currentTimeMillis(); 23 System.out.println("manyInsert()执行时间为:"+(end-start)+"ms"); manyInsert()执行时间为:937ms 对比分析: 发现采用这种方式的批量插入性能提升最明显,有10倍以上的性能提升。所以这种方式是我推荐的批量插入方式! 六、多线程插入 在第五种方式的基础上采用多线程插入。 代码: 1final Connection conn=source.getConnection(); 输出结果:2 for(int j=0;j<3;j++) 3 { 4 Thread t=new Thread(){ 5 @Override 6 public void run() { 7 try 8 { 9 long start=System.currentTimeMillis(); 10 Statement s=conn.createStatement(); 11 StringBuilder sql=new StringBuilder(""); 12 for(int j=0;j<100;j++) 13 { 14 conn.setAutoCommit(false); 15 sql=new StringBuilder(""); 16 sql.append("insert into user (id,name) values "); 17 for(int i=0;i<1000;i++) 18 { 19 if(i==999) 20 sql.append("('").append(i+1).append("',").append("'cxh')"); 21 else 22 sql.append("('").append(i+1).append("',").append("'cxh'),"); 23 } 24 s.execute(sql.toString()); 25 conn.commit(); 26 } 27 s.close(); 28 long end=System.currentTimeMillis(); 29 System.out.println("multiThreadBatchInsert()执行时间为:"+(end-start)+"ms"); 30 } 31 catch(Exception e) 32 { 33 e.printStackTrace(); 34 } 35 } 36 }; 37 t.start(); 38 //t.join(); 39 } multiThreadBatchInsert()执行时间为:2437ms multiThreadBatchInsert()执行时间为:2625ms multiThreadBatchInsert()执行时间为:2703ms 注意:上面我采用的是三个线程插入30w条数据。 取最大时间为2703ms,较上面的937ms,基本还是三倍的时间。 所以发现此时多线程也解决不了批量数据插入问题。原因就是,这时候的性能瓶颈不是CPU,而是数据库! 七、InnoDB引擎和MyISAM引擎的比较 最后,分析一下,这两个引擎对批量数据插入的影响。 先建立user2数据表: CREATE TABLE `user2` ( `id` varchar(50) NOT NULL, `seqid` bigint(20) NOT NULL auto_increment, `name` varchar(50) NOT NULL, PRIMARY KEY (`seqid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 代码: 1Connection conn=source.getConnection(); 输出结果:2 conn.setAutoCommit(false); 3 Statement s=conn.createStatement(); 4 StringBuilder sql=new StringBuilder(""); 5 long start=System.currentTimeMillis(); 6 for(int j=0;j<100;j++) 7 { 8 sql=new StringBuilder(""); 9 sql.append("insert into user2 (id,name) values "); 10 for(int i=0;i<1000;i++) 11 { 12 if(i==999) 13 sql.append("('").append(i+1).append("',").append("'cxh')"); 14 else 15 sql.append("('").append(i+1).append("',").append("'cxh'),"); 16 } 17 s.execute(sql.toString()); 18 conn.commit(); 19 } 20 s.close(); 21 conn.close(); 22 long end=System.currentTimeMillis(); 23 System.out.println("manyInsert2()执行时间为:"+(end-start)+"ms"); manyInsert2()执行时间为:3484ms 注意:第七项的代码和第五是一样的,除了数据表名称不同(user、user2) 但是, InnoDB :3484ms MyISAM:937ms 所以,MyISAM引擎对大数据量的插入性能较好。 总结: 对于大数据量的插入,建议使用insert into tableName (x,xx,xxx) values(x,xx,xxx),(xx,xxx,xxxx)…,的方式,引擎建议使用MyISAM引擎。 友情提醒:本博文章欢迎转载,但请注明出处:陈新汉 |
|