SQLServer中update操作怎么优化

SQLServer中update操作如何优化



   前几日做了一个测试,目的要得出一个结论,单纯的insert、update、select在百万数据量时的表现。但是测试过程中发现修改操作的表现十分异常,特向各位请教。下面简单描述一下我的环境与方法。

  程序引入c3p0连接池,然后直接用jsp取连接操作,没有使用spring、hibernate等框架,数据库sqlserver2008,web服务器tomcat 6.0.26,数据库与web服务器各一台机器。

  数据库连接池最大200个连接,tomcat最大线程数1000。

  表结构,id为主键

 SQLServer中update操作怎么优化

并有唯一索引

CREATE UNIQUE NONCLUSTERED INDEX [IX-MEMBER] ON [dbo].[members]
(
 [name] ASC,
 [id_card] ASC
)

  测试脚本,为避免各虚拟用户修改同一条数据,事先缓存1万条数据,然后2000用户顺序来取数据,去做更新。

  测试方法,每虚拟用户每5秒执行一次请求,最高2000用户。每秒上两个用户。此时160万左右的数据量,结论让人。。。,上图吧


SQLServer中update操作怎么优化

 

图一:虚拟用户数 


SQLServer中update操作怎么优化

 

图二:每秒响应点击数

 


SQLServer中update操作怎么优化
 
 图三:事务的执行时间

 

   每秒响应20次左右,事务响应时间也是一路飙升。没有分析出缘由。

  后来同样的表结构,和数据量,导入orcale数据库,同样的测试方法,结果如下,继续上图


SQLServer中update操作怎么优化

 

图四:orcale测试时,虚拟用户数
 
SQLServer中update操作怎么优化

 

图五:orcale测试时,每秒响应的点击数(天啊600+,但后面出现了连接数过多错误,暂且不管它)
 
SQLServer中update操作怎么优化
 

图六:orcale测试时,事务响应时间,一直在0秒徘徊。

 

  得到这个结果,小弟无语了,怎么可能?还望各路大侠给个分析思路!如有类似测试分享,不胜感激!!!

 

 

 

 

 

1 楼 bd_cool 2011-09-28  
附上修改部分代码

/**
	 * 更新对象
	 * @Title: update 
	 * @param m
	 * @return boolean
	 * @throws
	 */
	public boolean update(Member m){
		Log.debug("update(Member)...");
		boolean ret = false ;
		Connection con = DbBaseSource.getConnection(baseType);
		PreparedStatement pstm = null;
		if(con != null){
			long st = Calendar.getInstance().getTimeInMillis();
			Log.debug("update:" + m.toString());
			try {
				//con.setAutoCommit(false);
				//con.setTransactionIsolation(con.TRANSACTION_READ_UNCOMMITTED);
				String sql = "update members set sex=?,birthday=?," +
						"home_address=?,phone=?,mobile=?,email=?,post_address=?," +
						"post_code=?,nation=?,degree=? " +
						"where id=? ";//and name=? and id_card=?
				pstm = con.prepareStatement(sql);
				pstm.setInt(1, m.getSex());
				pstm.setTime(2, new Time(m.getBirthday().getTime()));
				pstm.setString(3, m.getHomeAddress());
				pstm.setString(4, m.getPhone());
				pstm.setString(5, m.getMobile());
				pstm.setString(6, m.getEmail());
				pstm.setString(7, m.getPostAddress());
				pstm.setString(8, m.getPostCode());
				pstm.setInt(9, m.getNation());
				pstm.setInt(10, m.getDegree());
				pstm.setString(11, m.getId());
				//pstm.setString(12, m.getName());
				//pstm.setString(13, m.getIdCard());
				int n=0;
				//synchronized(updateLock){
					n = pstm.executeUpdate();
				//}
				//con.commit();
				if(n == 1){
					ret = true;
					Log.debug("updateSUCC!!");
				}
			} catch (Exception e) {
				try {
					if(con != null){
						con.rollback();
					}
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
				e.printStackTrace();
			} finally {
				long et = Calendar.getInstance().getTimeInMillis();
				long t = et - st;
				if(t > OP_TIMEOUT * 1000){
					Log.debug("执行超过" + OP_TIMEOUT + " S, op=S_UP, m.id=" + m.getId(),t);
				}
				try {
					if(pstm != null){
						pstm.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					if(con != null){
						con.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}else{
			Log.debug("updateFailed!!");
		}
		Log.debug("updateEnd");
		return ret;
	}