关于executeBatch()执行速度缓慢问题的疑问

仓井NULL 2018-03-21 06:04:29
如题,在SQL SERVER 2008处理大量数据的时候使用executeBatch()方法,在Insert时处理很快,而在update的时候会有很长的延时(猜测是每次都单独提交了,但是在程序中已经将自动提交关闭)

源码如下:

public class Satisfaction {
protected Log log = LogFactory.getLog(getClass());
public void service(Connection con_ltsms, String isAreaVersion,
String op_hosid, String op_id, String audit_flag, String type_from) {

String sql_cr = null;
String sql_count = null;
PreparedStatement pt_cr = null;
PreparedStatement pt_count = null;
ResultSet rs_cr = null; // 记录结果集
ResultSet rs_count = null;
int temp_i = 0; // 临时提交的一个变量
int temp_k = 0; // 临时提交的一个变量
int batchSize = 500;

try {
sql_cr = "SELECT * FROM t1 ";
sql_count = "SELECT count(*) FROM t1";
pt_cr = con_ltsms.prepareStatement(sql_cr);
pt_count = con_ltsms.prepareStatement(sql_count);

rs_cr = pt_cr.executeQuery();
rs_count = pt_count.executeQuery();
PreparedStatement pt_ques = null;

int count = 0;
while (rs_count.next()) {
count = Integer.parseInt(rs_count.getString(1)); // 获取总的记录数,用于后面的批量提交
}

// 以下是插入t2表,由于使用批量插入
PreparedStatement pstmt_sms = null;
String sql_sms = "insert into t2(a1,a2) "
+ "values (?,?)";
pstmt_sms = con_ltsms.prepareStatement(sql_sms);
con_ltsms.setAutoCommit(false);
// 以上是插入t2表

// 以下是更新t3表
String sql_flag = "UPDATE t3 SET a1=? WHERE a2=?";
PreparedStatement pt_flag = con_ltsms
.prepareStatement(sql_flag);
// 以上是更新t3表

while (rs_cr.next()) { // <开始> 逐记录处理
pstmt_sms.setString(1, rs_cr.getString("a1"));
pstmt_sms.setString(2, rs_cr.getString("a2"));
temp_i++;

if (((temp_i != 0) && (temp_i) % batchSize == 0)
|| (temp_i == count)) {
pstmt_sms.executeBatch(); // 每1000条提交一次最后一条提交一次//此处提交可以很快执行完成
con_ltsms.commit();
pstmt_sms.clearBatch(); // 提交后,Batch清空。
}


pt_flag.setString(1, a1);
pt_flag.setString(2, a2);

temp_k++;
pt_flag.addBatch();

if (((temp_k != 0) && (temp_k) % batchSize == 0)
|| (temp_k == count)) {
pt_flag.executeBatch(); // 每1000条提交一次//最后一条提交一次 此处执行会有停顿,猜测还是单条提交而不是批量提交
con_ltsms.commit();
pt_flag.clearBatch(); // 提交后,Batch清空。
}

}
} catch (Exception exp) {
try {
con_ltsms.rollback(); //程序运行出错,事物的回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally {
con_ltsms.setAutoCommit(true);
}

}
...全文
2638 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
菜宇 2019-11-13
  • 打赏
  • 举报
回复
引用 13 楼 qq_37693217 的回复:
楼主有解决吗,我目前也是这个问题,批量更新到executeBatch就卡住不动了,三十万数据,卡一个小时还不动
你这是要死哦,一次批量30W直接插? 你想象一下一台货车一次性装30吨的货的场面....
菜宇 2019-11-13
  • 打赏
  • 举报
回复
引用 11 楼 ChasingdreamLY 的回复:
这位小哥,,我们问题一样,速度差不多,1000条数据/18秒,但是我的数据有一百多万,而且我对每列都要作update,我的属性列有2400+,,这个运行开销不可想象,有什么解决办法吗,网上查的什么事务提交,批处理我都加进去了,,现在就是这样一个运行速度。
JDBC的瓶颈吧?我1000条稳定12S,应该快不到哪里去了,你那个应该是要用SPARK或者MR跑了
qq_24376353 2018-12-03
  • 打赏
  • 举报
回复
楼主在么??我目前也是这个问题,先批量插入之后再进行批量更新,结果出现更新效率非常缓慢,基本上是10多秒才能执行500条
ChasingdreamLY 2018-08-25
  • 打赏
  • 举报
回复
这位小哥,,我们问题一样,速度差不多,1000条数据/18秒,但是我的数据有一百多万,而且我对每列都要作update,我的属性列有2400+,,这个运行开销不可想象,有什么解决办法吗,网上查的什么事务提交,批处理我都加进去了,,现在就是这样一个运行速度。
爱写Bug的麦洛 2018-03-23
  • 打赏
  • 举报
回复
引用 4 楼 qq_35800047 的回复:
[quote=引用 3 楼 Milogenius 的回复:] 麻烦问一下,你的表有没有建索引?
没有的,需要建索引是吗?[/quote] 不是的,如果有索引,你更新索引字段,会比较慢
仓井NULL 2018-03-23
  • 打赏
  • 举报
回复
引用 9 楼 Milogenius 的回复:
[quote=引用 4 楼 qq_35800047 的回复:] [quote=引用 3 楼 Milogenius 的回复:] 麻烦问一下,你的表有没有建索引?
没有的,需要建索引是吗?[/quote] 不是的,如果有索引,你更新索引字段,会比较慢[/quote] 嗯,学到了,谢谢啊
仓井NULL 2018-03-22
  • 打赏
  • 举报
回复
引用 5 楼 maradona1984 的回复:
如果目标表很大,update需要先查询,你得检查更新的搜索条件是否有索引
已经加了索引,速度变得快很多,但是提升不是很明显 我之前没有使用批量提交的速度是:260条记录/分钟 现在程序运行(使用批量提交):3000条记录/分钟
maradona1984 2018-03-22
  • 打赏
  • 举报
回复
如果目标表很大,update需要先查询,你得检查更新的搜索条件是否有索引
仓井NULL 2018-03-22
  • 打赏
  • 举报
回复
引用 3 楼 Milogenius 的回复:
麻烦问一下,你的表有没有建索引?
没有的,需要建索引是吗?
仓井NULL 2018-03-22
  • 打赏
  • 举报
回复
好像每次都查询一遍也是不行的,到了17500条记录之后也会报错

仓井NULL 2018-03-22
  • 打赏
  • 举报
回复
还有个问题,我在插入前需要查询另外一张表:如果不满足条件就不插入,这样的话会拖慢程序的运行速度 为了提升程序运行的速度 我用了map来存贮查询的记录,使用Key-value的形式来取值判断,若满足则插入 这样做确实提升了程序运行的速度,但是每次程序执行到13000条之后就会被终止,提示内存溢出的问题 后来网上查看:map理论上是可以无限大的,但是机器的内存是有限的~~~ 那么问题来了,我现在还是要每次用数据库去查询,而不是将所有的待查询记录提前放到MAP中吗
爱写Bug的麦洛 2018-03-21
  • 打赏
  • 举报
回复
麻烦问一下,你的表有没有建索引?
仓井NULL 2018-03-21
  • 打赏
  • 举报
回复
问题补充: 1.第一个批量提交可以确定是很快完成的,第二个批量提交可以确定是在执行pt_flag.executeBatch()时,出现“卡住的情况” 2.第二个批量提交(批量更新)的语句,在客户端执行时(10万条记录),一起更新2秒就可以执行完成
仓井NULL 2018-03-21
  • 打赏
  • 举报
回复
奇怪的是insert批量提交可以很快完成而在update时,500条数据可能就会被卡住一分钟,求大神指点下哪里有问题(源代码很长,我这个是把不相关的东西全部全部去掉了)

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧