JDBC更新一个大表的速度怎么那么慢?

badhorse 2006-12-21 09:11:01

我用的是Sql server数据库,表大约有150万条纪录
在Java程序中使用Sql语句更新表中的一条纪录,要花超过30秒的时间。但使用查询分析器执行该语句,在1秒内即可执行完毕。

请大家指教!
...全文
367 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
lixiaoxue85 2006-12-21
  • 打赏
  • 举报
回复
速度永远不是瓶颈
mathsfan 2006-12-21
  • 打赏
  • 举报
回复
这个年代效率最重要,语句写的再好,执行不快还是白搭```
badhorse 2006-12-21
  • 打赏
  • 举报
回复
看来只能先使用普通Statement语句组装Sql了, 原语句有90多个参数, 会是一条非常丑陋的语句。唉...
badhorse 2006-12-21
  • 打赏
  • 举报
回复
我试了微软的jdbc驱动和JDTS, 结果一样。
badhorse 2006-12-21
  • 打赏
  • 举报
回复
我查了些资料, 好像是数据库处理prepareStatement使用的执行计划于普通Statement的执行计划不同。
dreamover 2006-12-21
  • 打赏
  • 举报
回复
可能是sqlserver的jdbc驱动里对prepareStatement的处理方式的问题
badhorse 2006-12-21
  • 打赏
  • 举报
回复
呵呵, 我随便用的一个号码, 不知道是不是有效号码。
marckle 2006-12-21
  • 打赏
  • 举报
回复
调试一下,看看到底具体那一段执行时间长,然后想办法优化这一段。标准的SQL都很快的,用了上层的一些函数就会数量级的慢。
fool_leave 2006-12-21
  • 打赏
  • 举报
回复
把私人信息隐藏一下吧

badhorse 2006-12-21
  • 打赏
  • 举报
回复
什么意思呀
lcllcl987 2006-12-21
  • 打赏
  • 举报
回复
"where user_mobile = '8613910866967' and USSDPortal = '138*11' " +
//'8613910866967' 但愿是假号码
badhorse 2006-12-21
  • 打赏
  • 举报
回复
不用ReqDBReq我试了一下, 还是同样慢。
shine333 2006-12-21
  • 打赏
  • 举报
回复
Req2DBReq会有问题吗?

你干吗不试试sql=".... where user_mobile = ? and USSDPortal = ? .... "

pstmt.setString(1, "86....."); //但愿那个测试的是假号码

badhorse 2006-12-21
  • 打赏
  • 举报
回复
我把代码写成下面这样, 速度就很快了, 难道使用参数复制的方式组装Sql语句会有性能问题?

private void updateStatTable(Req2DBReq req)
{
String sql = "update t_stat_hour_user set FNum = FNum + 1 " +
"where user_mobile = '8613910866967' and USSDPortal = '138*11' " +
"and time_begin = cast('2006-12-21 09:00:00' as datetime)";


Connection conn = null;
PreparedStatement pstmt = null;

try
{
Date now = new Date();

conn = DBConnectionPool.getInstance().getConnection();
pstmt = conn.prepareStatement(sql);

pstmt.executeUpdate();
}
catch (SQLException e)
{
DsmpProxyApp.getLog().error(
"数据库操作错误(Req2DBHandler):" + e.getMessage());
}
finally
{
DBTools.close(conn, pstmt, null);
conn = null;
pstmt = null;
}

}
badhorse 2006-12-21
  • 打赏
  • 举报
回复
我在查询分析器中执行以下语句, 一瞬间即可完成:

update t_stat_hour_user set FNum = FNum + 1
where user_mobile = '8613910866967' and USSDPortal = '138*11' and time_begin = cast('2006-12-21 09:00:00' as datetime)

badhorse 2006-12-21
  • 打赏
  • 举报
回复
我把原来的函数精简了, 结果一样, 下面是完整的函数:
private void updateStatTable(Req2DBReq req)
{
String sql = "update t_stat_hour_user set FNum = FNum + 1 where user_mobile = ? and USSDPortal = ? and time_begin = ? ";


Connection conn = null;
PreparedStatement pstmt = null;

try
{
Date now = new Date();

conn = DBConnectionPool.getInstance().getConnection();
pstmt = conn.prepareStatement(sql);

GregorianCalendar timeBegin = null;

timeBegin = new GregorianCalendar();
timeBegin.setTime(now);
timeBegin.set(GregorianCalendar.MINUTE, 0);
timeBegin.set(GregorianCalendar.SECOND, 0);
timeBegin.set(GregorianCalendar.MILLISECOND, 0);

pstmt.setString(1, req.getMobile());
pstmt.setString(2, req.getUSSDPortal());
pstmt
.setTimestamp(3, new Timestamp(timeBegin.getTime().getTime()));


pstmt.executeUpdate();
}
catch (SQLException e)
{
DsmpProxyApp.getLog().error(
"数据库操作错误(Req2DBHandler):" + e.getMessage());
}
finally
{
DBTools.close(conn, pstmt, null);
conn = null;
pstmt = null;
}

}
fool_leave 2006-12-21
  • 打赏
  • 举报
回复
你这个sql在修改参数后和你在查询分析器里面的完全一样吗?

主要是where语句,一定一样吗?
newste 2006-12-21
  • 打赏
  • 举报
回复
不过我觉得可能是你的代码有问题,你单独写个方法测试下看看,是不是也需要30秒;
newste 2006-12-21
  • 打赏
  • 举报
回复
关注下
hbwhwang 2006-12-21
  • 打赏
  • 举报
回复
不会吧?
加载更多回复(10)

62,616

社区成员

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

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