当oracle的DML操作性能受到影响可以从以下因素方面来考虑改善新能。
1)where子句的效率
where子句是否的条件关联是否利用到了索引,统计信息的维护例直方图等来帮助提升效率的手段
2)索引带来的成本
索引虽然为查询提升了效率但是对于增删改操作确定带来了成本。向表中插入一条数据时会在索引空间中生成一条记录,oracle的索引时以b树的方式来维护的。当插入的数据量过多是需要对节点进行调整来恢复索引树的高度
3)触发器的成本
4)完成性约束的成本
当触发大批量的操作的时候触发器和完整性的约束成本也不容忽视。
- insert语句的优化:
- 使用批量操作
批量操作是尽量将对同一张的表的多次插入合并到一起一次插入多条数据,减少数据库和应用程序之间的交互带来的开销。
- 使用append直接载入数据
使用append直接载入数据,避免了常规插入式数据写入缓存的一步,而是直接将数据写入磁盘中。常规的insert写入高速缓存中然后将高速缓存中,然后检索出段空间中的数据块中可插入数据空间将数据写入。append之间申请空闲的数据块将数据插入。append操作减少了对高速缓存区的争用以及redolog日志的产生量。使用append hit的时候需要考虑到系统磁盘io子系统的性能。对于慢速的IO子系统来说可能带不来性能的提升甚至有可能造成系能下降。同时需要注意的是append将会给表加一个全表锁或或者一个分区锁
- 使用并行来提升效率
使用并行线程可以是多个线程来完成完成插入操作提升性能。但是需要考虑到磁盘的驱动。如果是但磁盘驱动可能会将并行的写请求加入到队列中串行的操作。这样并不能带来系能的提升,反而可能因为多线程对资源的争用带来系能的下降
- 使用insert all语句来同时对多个表操作
当出现以下从一个表中获取数据插入到根据不同条件插入不同的表时可以考虑使用insert all。譬如
- insert all
- when a = xxx into A (col1,clo2)
- values(v1,v2)
- when a = xxx into B(col1,col2)
- values(v1,v2)
- select * from B
- 使用批量操作
- 删除优化
- 使用truncate避免使用delete
默认TRUNCATE要回收空间,且会将所有的脏块写回到数据文件。truncate table后,oracle会回收表和其表中所在的索引到initial 大小并重置HWM。所以truncate table可能比delete慢
- 直接删除整个分区
- 使用逻辑删除
- 使用truncate避免使用delete
- 更新
update table A aset a.c1 = (select b.c1 from B b where a.id = b.id)where exists(select 1 from B b where a.id = b.id )
可以考虑使用以下方式来更新表中的数据避免对B的两次查询
update (select a.c1 a_c1, b.c1 b_c1 from A a, B where a.id = b.id) set a_c1 = b_c1
时间: 2024-10-06 08:33:25