日期:2014-05-16  浏览次数:20911 次

Java的一个for循环中执行两句sql时的性能问题
最近在做一个性能调查时,遇到一个问题很是费解。
在一个DB更新用的循环中执行了以下的逻辑。

for(Object obj:List){
  执行一次DB的update操作;
  执行一次DB的insert操作;
}

这样处理的话,计算过执行500次的update和insert时间需要11秒左右。但是,如果修改成以下方式:
for(Object obj:List){
  执行一次DB的update操作;
}
for(Object obj:List){
  执行一次DB的insert操作;
}
同样的执行500次的话(List中有500条记录),只需要3秒。

造成这个结果的主要原因是什么?
是sql替换之后需要parse造成的吗?
不知道应该查什么资料,请教了

------解决方案--------------------
应该涉及到
1、Oracle的TX锁(行级锁、事务锁)
2、TM锁(表级锁)
这些吧,等大牛 来解疑
------解决方案--------------------
顶一下,大牛来解释下吧,困惑了好久了。

------解决方案--------------------
关注中。。持续跟进,有意思
------解决方案--------------------
分开的话,估计是你做update的时候把所需的块全部灌进内存(buffer cache),然后做insert的时候几乎都是内存计算了

------解决方案--------------------
得看你具体update什么,insert什么了以及用到的where条件和索引情况,insert一般不费时,主要是update费时,update+insert,数据会越来越多,而update后再insert,数据相对少一点,可以试试把insert放第一个循环看看会是什么效果
------解决方案--------------------
恩,是的的确是update消耗的时间更多。

再把问题描述具体一些:
transaction begin
for(Object obj:List){
  执行一次DB的update操作;
  执行一次DB的insert操作;
}
transaction commit.
这样处理的话,计算过执行500次的update和insert时间需要11秒左右。
其中update大概耗时10.5秒,insert值需要0.5秒。

但是,如果修改成以下方式:
transaction begin
for(Object obj:List){
  执行一次DB的update操作;
}
for(Object obj:List){
  执行一次DB的insert操作;
}
transaction commit

同样的执行500次的话(List中有500条记录),只需要3秒。
其中update大概耗时2.5秒,insert值需要0.5秒。

更新做的作业如下:依据record的几个关键字段把表中的的flag更新为1,
*******************************************
UPDATE /*+ hint */ table_name
SET order_flag = '1'
WHERE productName = :productName
AND serialNo = :serialNo
AND demandName = :demandName
AND order_flag is null
*******************************************

insert就是简单的登录类似记录。


------解决方案--------------------
再来顶一下,大牛呢,求教了啊.