JDBC批量插入数据效率分析
对于需要批量插入数据库操作JDBC有多重方式,本利从三个角度对Statement和PreparedStatement两种执行方式进行分析,总结较优的方案。
当前实现由如下条件:
执行数据库:Mysql
执行数据数量:10万条
执行前提:执行差入数据库钱均需要提供空表,防止数据量大造成的影响
执行方式:Statement和PreparedStatement两种方式
执行步骤开始:
1、创建表
CREATE TABLE T_PRODUCT (
ID bigint(12) NOT NULL AUTO_INCREMENT COMMENT '主键',
NAME varchar(60) NOT NULL COMMENT '产品名称',
WEIGHT varchar(60) NOT NULL COMMENT '产品重量',
MARK varchar(60) NOT NULL COMMENT '产品说明',
PRIMARY KEY (ID)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='产品表';
2、编写操作数据库工具类
package com.luwei.test.jdbc; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle; /**
* <Description> TODO<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 <br>
* @since V1.0<br>
* @see com.luwei.test.jdbc <br>
*/
public class JdbcTemplate {
private static String DRIVER_CLASS_NAME = null;
private static String URL = null;
private static String USERNAME = null;
private static String PASSWORD = null; static {
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
DRIVER_CLASS_NAME = bundle.getString("jdbc.driverClassName");
URL = bundle.getString("jdbc.url");
USERNAME = bundle.getString("jdbc.username");
PASSWORD = bundle.getString("jdbc.password");
} /**
*
* <Description> 获取数据库连接<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:19:41 <br>
* @return
* @throws Exception
* <br>
*/
public static Connection getConnection() throws Exception {
Class.forName(DRIVER_CLASS_NAME);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
return connection;
} /**
*
* <Description> 提交事务<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:20:48 <br>
* @param connection
* <br>
*/
public static void commit(Connection connection) {
try {
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> 开启事务<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:23:56 <br>
* @param connection
* <br>
*/
public static void beginTx(Connection connection) {
try {
connection.setAutoCommit(false);
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> 回滚<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:24:33 <br>
* @param connection
* <br>
*/
public static void rollback(Connection connection) {
try {
connection.rollback();
}
catch (SQLException e) {
e.printStackTrace();
}
} /**
*
* <Description> TODO<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2017年1月9日 下午10:28:49 <br>
* @param statement
* @param connection
* <br>
*/
public static void releaseDb(Statement statement, Connection connection) {
try {
statement.close();
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
3、执行数据库插入操作
3.1、使用Statement直接插入,三次执行耗时:41979 42608 42490
@Test
public void testStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement();
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String sql = "insert into t_product values(null,'name_" + i + "','120kg','mark_" + i + "')";
statement.execute(sql);
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
3.2、使用PreparedStatement直接插入,三次执行耗时:22808 24675 22281
@Test
public void testPreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection);
String sql = "insert into t_product values(null,?,?,?)"; statement = connection.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
statement.setString(1, "name_" + i);
statement.setString(2, "120kg");
statement.setString(3, "mark_" + i);
statement.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
3.3、使用BatchStatement直接插入,三次执行耗时:15342 15235 15485
@Test
public void testBatchStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement();
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String sql = "insert into t_product values(null,'name_" + i + "','120kg','mark_" + i + "')";
statement.addBatch(sql); if ((i + 1) % 100 == 0) {
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.clearBatch();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
3.4、使用BatchPreparedStatement直接插入,三次执行耗时:21913 22045 23291
@Test
public void testBatchPreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection);
String sql = "insert into t_product values(null,?,?,?)"; statement = connection.prepareStatement(sql);
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
statement.setString(1, "name_" + i);
statement.setString(2, "120kg");
statement.setString(3, "mark_" + i);
statement.addBatch();
if ((i + 1) % 100 == 0) {
statement.executeBatch();
statement.clearBatch();
}
}
statement.executeBatch();
statement.clearBatch();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
3.5、使用采用多Value值Statement直接插入,三次执行耗时:2931 3007 3203 2964
@Test
public void testMutilValueStatement() {
Connection connection = null;
Statement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); statement = connection.createStatement(); StringBuffer sql = new StringBuffer("insert into t_product values");
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
if (i != 0) {
sql.append(",");
}
sql.append("(null,'name_" + i + "','120kg','mark_" + i + "')");
}
statement.execute(sql.toString());
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
3.6、使用采用多Value值PreparedStatement直接插入,三次执行耗时:3356 3218 3233
@Test
public void testMutilValuePreparedStatement() {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = JdbcTemplate.getConnection();
JdbcTemplate.beginTx(connection); StringBuffer sql = new StringBuffer("insert into t_product values");
long begin = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
if (i != 0) {
sql.append(",");
}
sql.append("(null,'name_" + i + "','120kg','mark_" + i + "')");
}
statement = connection.prepareStatement(sql.toString());
statement.executeUpdate();
long end = System.currentTimeMillis();
System.out.println(end - begin);
JdbcTemplate.commit(connection);
}
catch (Exception e) {
e.printStackTrace();
JdbcTemplate.rollback(connection);
}
finally {
JdbcTemplate.releaseDb(statement, connection);
}
}
通过以上时间结果得出如下数据表格:


总结:通过如上的数据对比发现
1、PreparedStatement执行数据库插入比使用Statement执行数据库插入明显有性能优势,原因归功于PreparedStatement能够预先对SQL进行编译,做到执行时进行SQL共享
2、执行数据库批量操作是使用Batch方式对数据库采用批次操作能够明显提升数据库操作性能能
3、不管是直接多次插入数据库还是采用Batch方式执行数据库的插入,均会发送多次SQL脚本去执行,这样明显没有发送一次SQL脚本执行来的效率高
4、采用单SQL执行数据库批量操作时Statement对比PreparedStatement有微弱的优势,可能是Statement不需要判断注参的原因吧
JDBC批量插入数据效率分析的更多相关文章
- JDBC批量插入数据优化,使用addBatch和executeBatch
JDBC批量插入数据优化,使用addBatch和executeBatch SQL的批量插入的问题,如果来个for循环,执行上万次,肯定会很慢,那么,如何去优化呢? 解决方案:用 preparedSta ...
- MySQL:JDBC批量插入数据的效率
平时使用mysql插入.查询数据都没有注意过效率,今天在for循环中使用JDBC插入1000条数据居然等待了一会儿 就来探索一下JDBC的批量插入语句对效率的提高 首先进行建表 create tabl ...
- android批量插入数据效率对比
对比在android中批量插入数据的3中方式对比(各插入1W条数据所花费的时间): 1. 一个一个插入 /** * 向表中插入数据 * * @param openHelper * @param app ...
- 【实践】jdbc批量插入数据
参考文献:http://my.oschina.net/u/1452675/blog/203670 http://superjavason.iteye.com/blog/255423 /*测试批量写入数 ...
- jdbc批量插入数据
//插入很多书(批量插入用法) public void insertBooks(List<Book> book) { final List<Book> tempBook=b ...
- Java使用JDBC连接数据库逐条插入数据、批量插入数据、以及通过SQL语句批量导入数据的效率对比
测试用的示例java代码: package com.zifeiy.test.normal; import java.io.File; import java.io.FileOutputStream; ...
- 向mysql中批量插入数据的性能分析
MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下 CREATE TABLE example (example_id INT NOT NULL,name VARCHAR( 5 ...
- JDBC(五)—— 批量插入数据
批量插入数据 @Test public void testInsert() throws Exception { Connection conn = null; PreparedStatement p ...
- Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案
转自http://www.cnblogs.com/fnz0/p/5713102.html 不知道自己什么时候才有这种钻研精神- -. 1 背景 系统中需要批量生成单据数据到数据库表,所以采用 ...
随机推荐
- LSI MegaCl i命令使用1
MegaCli命令使用:cd /opt/MegaRAID/MegaCli/MegaCli -AdpAllInfo -aAll [显示所有适配器信息]MegaCli -LDInfo -Lall ...
- HDU -2674 N!Again(小技巧)
这道题有个小技巧,就是既然是n!,那么对2009求余,只要大于2009!,那么一定是0,在仔细想想会发现,根本到不了2009,只要到2009的最大质因数就行了,为什么呢?因为最大质因数是最大的一个不能 ...
- Matcher Pattern 正则表达式 示例
示例 public class Test { public static void main(String[] args) throws IOException { Patte ...
- 设计模式之—简单工厂模式<Simple Factory Pattern >
简单工厂模式结构图: 简单工厂模式以简单的加减乘除运算为例: 运算符类(Operation): namespace CalcTest.Simple_Factory_patterns { class O ...
- python运行时间计算之timeit
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000) stmt:statement ...
- Javascript 常用函数【1】
1:基础知识 1 创建脚本块 1: <script language=”JavaScript”> 2: JavaScript code goes here 3: </script&g ...
- access 2007 vba 开发中学到的知识(二)
文件的导入和导出 excel 'excel导入Private Sub btnInExcel_Click() Dim strSelectFile As StringWith Application.Fi ...
- validate插件深入篇
1.使用valid()来验证表单是否填写正确: <form id="mainform"> <button id="check">< ...
- 使用scrapy制作的小说爬虫
使用scrapy制作的小说爬虫 爬虫配套的django网站 https://www.zybuluo.com/xuemy268/note/63660 首先是安装scrapy,在Windows下的安装比 ...
- 遍历元素绑定事件时作用域是怎么回事啊,为什么要用this关键字,而直接使用元素本身就不行?
如下代码,将this改为rows[i]为啥不起作用了 var rows = document.getElementsByTagName("tr"); for(var i=0;i&l ...