Orace中大数据量的DML操作事务的优化

本篇文章,小编为大家浅谈PL/SQL语句在处理大数据量时,如何进行优化。

前几天,后台跑数据出现了一个令人头疼的事情,一个更新语句在更新数据时,非常的慢。语句写法如下。

	UPDATE TA_HT_A A SET (A.a,A.b,A.c) = 
	(SELECT B.a,B.b,B.c FROM TA_HT_B B 
	WHERE A.UUID = B.UUID AND B.EW = '1');

就这么简单的更新语句,对表加了索引,做了一些简单的优化操作,一次更新完,要花5、6个小时;而且整个跟新语句的耗费有一亿多,这个不夸张,确实有这么大(ps:两个表中的数据量本来就很大,一个是千万级的,一个是百万级的)。后台数据这么下去,一是时间不允许,二是有可能造成整张表被锁死。

小编只好另辟蹊径,对该更新语句的写法,操作方式进行优化。最后总结出了对这种大数据量的DML操作的优化方案。

一、MERGE INTO

语法:

	MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [...]...)  
	WHEN MATCHED THEN  
    		[UPDATE sql]  
	WHEN NOT MATCHED THEN  
   		 [INSERT sql] 
通过利用merge into对该更新语句进行改写后,代码如下:

	MERGE INTO TA_HT_A A
	USING TA_HT_B
	ON (A.UUID= B.UUID AND B.EW = '1')
	WHEN MATCHED THEN
        	UPDATE
             	SET A.a = B.a,
                    A.b = B.b,
                    A.c = B.c;
用MERGE INTO 改写后的更新语句耗费只有一百多万了,大大减少了更新时的耗费,虽然耗费还是很高,但是没办法,数据量本身就比较大,勉强还能接受。

二、BULK COLLECT与FORALL对大数据量优化操作

如果有大数据量的DML操作事务,在OLAP报表等低并发库里,并且强制归档模式中,采用BULK和FORALL会比较快。

相对使用普通游标循环提取数据出来处理的话会快很多。原因如下:

1、bulk collect into 到数组,可以一次性把数据提取出来,减少了循环当中PL/SQL和SQL引擎的切换时间;

2、forall in ......也是一次性提交数据导某个地方,也同样减少了循环当中PL/SQL和SQL引擎的切换时间;(数据太大,要合理设置limit,否则提取到数组的数据会爆了PGA的会话内存)

3、bulk内部操作对insert delete 做了优化采用批量方法,极大减少了redo和undo使用量;

4、当一个大数据量的insert会超级慢,如果分批,插入的总时间比一次插入省很多时间。

因为后台还在跑数据当中,所以后续的更新语句会加上。

你可能感兴趣的:(Orace中大数据量的DML操作事务的优化)