Oracle update特别慢,比insert慢很多很多
我用JDBC的PreparedStatement往Oracle的一个表里面插入数据和更新数据。
两个Connection创建两个PreparedStatement,一个用来执行insert另外一个用来执行update。
PreparedStatement使用批处理的方式,1000条commit一次。
表里面一共100W条数据,
执行3W条insert语句花了52秒;
执行3W条update语句花了1058秒。
表结构:
dept(deptno,dname,loc);
插入数据SQL:insert into TEST.DEPT(DEPTNO, DNAME, LOC) values (?, ?, ?)
更新数据SQL:update TEST.DEPT set DNAME = ?, LOC = ? where DEPTNO = ?
此表没有约束和索引。
请问,update为什么花这么长时间? 没更新1000条,花30-40秒。
------解决方案--------------------必然update比insert慢呀,insert没有主键情况下直接插入,速度很快,update要先去找到对应记录,在更新,你把DEPTNO建个索引,就会快很多了
------解决方案--------------------建表的PCTFree 和PCTUsed 参数设置,看看能不能改动下。update应该增大PCTFree
------解决方案--------------------
请问,update为什么花这么长时间? 没更新1000条,花30-40秒。
-----------------------------
这个牵涉到Oracle的内部实现机制,一般来说,insert只需要为新记录找到一个可插入的地方,然后将记录数据按照内部格式复制到对应的位置就可以了,加上你的表没有索引,因此也没有索引操作的时间消耗,所以快;对于update而言,多了很多操作,简单而言,
(1)因为没有索引,因此,需要更新前先需要通过全表扫描的方式来定位记录,这大概会消耗掉你所提的大部份时间;所以楼上有人建议你更新前先建合适的索引;
(2)需要为旧记录数据复制到称为回滚段的地方,以便保证数据可以正确回滚,因此,这里实际至少要处理两条记录的插入操作,就这点上,会比insert耗时在两倍以上;
(3)因为update可能会导致原记录所在页的空间不够存放新的数据,因此,需要将更新后的记录“迁移”到另外的数据页上,而这种迁移处理是非常耗时的。为了减少迁移发生,所以L3建议你增大PCTFREE的值。
------解决方案--------------------如大家说的,插入没有索引是很快的,但修改由于没有索引,会进行全表扫描,增加扫描的开销,建议你对DEPTNO 字段增加索引。
另外,如果这个表经常update会有些碎片,也会影响到更新的速度,可以定期对表进行碎片整理,如在线重建索引等。