论坛首页 Java企业应用论坛

update12条记录要用3分钟

浏览 15492 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-07-30   最后修改:2009-07-31
最近的一个工作,在原有的系统上添加一个功能。为了保持一致性,沿用原系统的ibatis框架。看了下之前的代码基本上了解怎么弄了。

代码测试,发现执行效率非常之差。

1.batch12条记录要500秒左右,并且得不到正确的结果

如下:
int num=this.executeBatch();


ibatis api给出的是:
Returns:
the number of rows updated in the batch


程序执行完毕,记录确实被update,但是num=0。找不到问题的关键,加上执行时间要500秒左右,遂放弃batch。

2.12条记录分别update,用时180秒。在mysql-front,执行也不过是几秒钟的事。

贴下代码吧,初学ibatis,这个效率实在让我害怕。

dao:
@Override
	public boolean updateEachStatusByNameEn(List<Constellation> constellationList) {
		int num=0;
		
		long begTime=new Date().getTime();
		Iterator<Constellation> i=constellationList.iterator();
		while(i.hasNext()){
			Constellation constellation=i.next();
			String tmp=constellation.getTodayDes();
			String todaydes=tmp.substring(tmp.indexOf('>',tmp.indexOf('>')+1)+1, tmp.length());
			constellation.setTodayDes(todaydes);
			try {
				sqlMapper.startTransaction();
				sqlMapper.update("CONSTELLATION.updateForBatch",constellation);
				sqlMapper.commitTransaction();
				num++;
			} catch (SQLException e) {
				num--;
				e.printStackTrace();
			}finally{
				try {
					sqlMapper.endTransaction();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		long endTime=new Date().getTime();
		logger.info("更新记录数:"+num+" ,耗时:"+(endTime-begTime)+" 毫秒。");
		return num==12;
	}


sqlmap:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="CONSTELLATION">
	<!--  
	<cacheModel id="CONSTELLATION-cache" type="LRU">
		<flushInterval hours="1" />
		<flushOnExecute statement="updateForBatch" />
		<property name="size" value="12" />
	</cacheModel>
 	 -->

 	 <resultMap class="com.kong.xiaoqiang.prototype.Constellation"  id="Constellation">
		<result column="nameen" jdbcType="CHAR" property="nameEn" />
		<result column="namezh" jdbcType="CHAR" property="nameZh" />
		<result column="modifytime" jdbcType="TIMESTAMP" property="date" />
		<result column="todaydes" jdbcType="VARCHAR" property="todayDes" />
	</resultMap>
	
	<update id="updateForBatch" parameterClass="com.kong.xiaoqiang.prototype.Constellation" >
		UPDATE constellation SET todaydes=#todayDes# WHERE nameen=#nameEn#
	</update>
	
	<select id="selectByNameEn" parameterClass="java.lang.String" resultMap="Constellation" >
		SELECT nameen,namezh,modifytime,todaydes FROM constellation WHERE nameen=#nameEn#
	</select>
</sqlMap>
   发表时间:2009-07-30  
blank 写道
这样不慢才怪


望赐教
0 请登录后投票
   发表时间:2009-07-31  
jacklondon 写道
Transaction 不应该放在循环里面吧?
怎么大家都不明白 Transaction 放哪里呢?



Transaction 不放在循环里我试了,快不了几秒。跟3分钟相比,九牛一毛。

主要是不能满足需求,如果有一条记录抓xml出现错误,那所有的都失败了,这不是我们想要的结果。
0 请登录后投票
   发表时间:2009-07-31  
 sqlMapper.update("CONSTELLATION.updateForBatch",constellation); 

  
   这个语句本身就是一个事务吧?如果想使用批量处理,贴一下我当初批处理的代码,希望对楼主有所帮助


public Object insertXXInfoBatch(final List<XXInfo> XXToAdd, final List<ZZInfo> ZZToAdd, final List<ZZInfo> ZZToUpdate) throws DataAccessException{
	    
		Object obj=this.getSqlMapClientTemplate().execute(new SqlMapClientCallback(){
	    public Object doInSqlMapClient(SqlMapExecutor executor)
	            {
	    
	       ........
	    }});
        return obj;
	    

}
0 请登录后投票
   发表时间:2009-07-31  
michael.softtech 写道
 sqlMapper.update("CONSTELLATION.updateForBatch",constellation); 

  
   这个语句本身就是一个事务吧?如果想使用批量处理,贴一下我当初批处理的代码,希望对楼主有所帮助


public Object insertXXInfoBatch(final List<XXInfo> XXToAdd, final List<ZZInfo> ZZToAdd, final List<ZZInfo> ZZToUpdate) throws DataAccessException{
	    
		Object obj=this.getSqlMapClientTemplate().execute(new SqlMapClientCallback(){
	    public Object doInSqlMapClient(SqlMapExecutor executor)
	            {
	    
	       ........
	    }});
        return obj;
	    

}



关于那个updateforBatch 不是真正的批处理,我没有改名字而已。

他对应的sql是

<update id="updateForBatch" parameterClass="com.kong.xiaoqiang.prototype.Constellation" >   
UPDATE constellation SET todaydes=#todayDes# WHERE nameen=#nameEn#   
</update> 


你是想说

sqlMapper.startBatch();
sqlMapper.executeBatch();

这样的代码等价于一个事务吧。

你的代码是spring的template。。回调函数里“...”的部分写类似"startBatch,update...update,excuteBatch"这样的代码?

这个我需要试一下

而且目前项目里没有spring的集成,即使可以解决效率问题的话,能用起来的可能性也为0...

0 请登录后投票
   发表时间:2009-07-31  
楼主可用JDBC代码来测试一下是否同样低效
这样可以判断是数据库的问题还是代码问题
如果是数据库问题,则多半是由于表数据量过大而没有加适当的索引造成效率低下
0 请登录后投票
   发表时间:2009-07-31  
这是我做的小功能
  • 大小: 131.5 KB
0 请登录后投票
   发表时间:2009-07-31  

我是指按照你目前的实现,是每一条记录更新都使用了一个新的事务。

如果把所有需要更新的记录放在一个List里面,然后在service方法里面把所有记录在一个事务里面做更新。

至于Spring,只是提供了一个获取sqlmap的途径,真正的数据操作还是使用ibatis的api来实现的,所以你可以把 Spring 忽略掉....
0 请登录后投票
   发表时间:2009-07-31  
不会这么慢吧~~很久之前做了一个Hibernate, JdbcTemplate,Ibaits批量插入数据对比,现在再跑下测试用列,结果如下:
--------------insert 10000条数据(oracle 10g)--------------
Hibernate : 40438 ms
JdbcTemplate().batchUpdate:123688 ms
Ibaits : 71718 ms

----------------------------------------------------------
这里面,JdbcTemplate实际是最慢的,有点出乎意料!

0 请登录后投票
   发表时间:2009-07-31  
lz用startBatch,execBatch看看呢
还有你们的nameen有没有索引,表记录有多少条?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics