MySQL Jdbc驱动的rewriteBatchedStatements参数 关于批处理

在使用mysql 数据库的时候如果需要批量添加,修改,删除功能则要设置rewriteBatchedStatements参数,这样才能真正起到批量添加的功能

// 开启批量添加

private String url="jdbc:mysql://localhost:3306/music?rewriteBatchedStatements=true";   

 

// 关闭批量添加

private String url="jdbc:mysql://localhost:3306/music?rewriteBatchedStatements=false";  

 

MySQL Jdbc驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,直接造成较低的性能。

 

只有把rewriteBatchedStatements参数置为true,驱动才会帮你批量执行SQL (jdbc:mysql://localhost:3306/mydb3?rewriteBatchedStatements=true)。不过,驱动具体是怎么样批量执行的?

 

另外,有人说rewriteBatchedStatements只对INSERT有效,有人说它对UPDATE/DELETE也有效。为此我做了一些实验(详见下文),结论是:这个选项对INSERT/UPDATE/DELETE都有效,只不过对INSERT它为会预先重排一下SQL语句

 

 

实验记录:未打开rewriteBatchedStatements时

 

未打开rewriteBatchedStatements时,根据wireshark嗅探出的mysql报文可以看出,

batchDelete(10条记录)  =>  发送10次delete请求

batchUpdate(10条记录)  =>  发送10次update请求

batchInsert(10条记录)  =>  发送10次insert请求

 

也就是说,batchXXX()的确不起作用

 

实验记录:打开了rewriteBatchedStatements后

打开rewriteBatchedStatements后,根据wireshark嗅探出的mysql报文可以看出

 

batchDelete(10条记录)  =>  发送一次请求,内容为”delete from t where id = 1; delete from t where id = 2; delete from t where id = 3; ….”

batchUpdate(10条记录)  =>  发送一次请求,内容为”update t set … where id = 1; update t set … where id = 2; update t set … where id = 3 …”

batchInsert(10条记录)  =>   发送一次请求,内容为”insert into t (…) values (…) , (…), (…)”

 

对delete和update,驱动所做的事就是把多条sql语句累积起来再一次性发出去;而对于insert,驱动则会把多条sql语句重写成一条风格很酷的sql语句,然后再发出去。官方文档说,这种insert写法可以提高性能(”This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements”)

 

一个注意事项

需要注意的是,即使rewriteBatchedStatements=true, batchDelete()和batchUpdate()也不一定会走批量:当batchSize <= 3时,驱动会宁愿一条一条地执行SQL。所以,如果你想验证rewriteBatchedStatements在你的系统里是否已经生效,记得要使用较大的batch.

实验代码

package cn.itcast.dome4;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.junit.Test;

import cn.itcast.dome2.jdbcUtils;

public class dome4 {

	@Test
	public void fun1() throws Exception {
		Connection con=jdbcUtils.getConnection();
		String sql="insert into stu values(?,?,?,?)";
		PreparedStatement pstmt=con.prepareStatement(sql);
		
		for(int i=0;i<10000;i++){
			pstmt.setInt(1, 1+i);
			pstmt.setString(2," stu_+"+i);
			pstmt.setInt(3, i);
			pstmt.setString(4, i%2==0?"nan":"nv");
			
			pstmt.addBatch();
		}
		long start=System.currentTimeMillis();
		pstmt.executeBatch();
		long end=System.currentTimeMillis();
		System.out.println(end-start);
		
		/*
		 * 不改配置时配置为
		 * jdbc:mysql://localhost:3306/mydb3
		 * 
		 * 的时候执行上述代码要很久大约6.8分钟
		*/
		
		/*将配置改为
		 * jdbc:mysql://localhost:3306/mydb3?rewriteBatchedStatements=true
		 *执行代码的时间大约不住1秒
		 */
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值