FOR迴圈與FORALL的效能比較

2022-02-07 05:30:26 字數 2447 閱讀 3643

通常在sql語句中給pl/sql變數賦值叫做繫結(binding),一次繫結乙個完整的集合稱為批量繫結(bulk binding)。

批量繫結(bulk binds)可以通過減少在pl/sql和sql引擎之間的上下文切換(context switches )提高了效能.

批量繫結(bulk binds)包括:

(i) input collections, use the forall statement,一般用來改善dml(insert、update和delete) 操作的效能

(ii) output collections, use bulk collect clause,一般用來提高查詢(select)的效能

forall的語法如下:

forall index in lower_bound..upper_bound sql_statement;

下面是乙個簡單測試,用以說明forall與for迴圈的效能差異。

sql> drop table blktest;

table dropped.

elapsed: 00:00:00.13

sql>

sql> create table blktest (num number(20), name varchar2(50));

table created.

elapsed: 00:00:00.08

sql>

sql> create or replace procedure bulktest

2 is

3 type numtab is table of number (20)

4 index by binary_integer;

56 type nametab is table of varchar2 (50)

7 index by binary_integer;

89 pnums numtab;

10 pnames nametab;

11 t1 number;

12 t2 number;

13 t3 number;

14 begin

15 for j in 1 .. 1000000

16 loop

17 pnums (j) := j;

18 pnames (j) := 'seq no. ' || to_char (j);

19 end loop;

2021 select dbms_utility.get_time

22 into t1

23 from dual;

2425 for i in 1 .. 1000000

26 loop

27 insert into blktest

28 values (pnums (i), pnames (i));

29 end loop;

3031 select dbms_utility.get_time

32 into t2

33 from dual;

3435 forall i in 1 .. 1000000

36 insert into blktest

37 values (pnums (i), pnames (i));

3839 select dbms_utility.get_time

40 into t3

41 from dual;

4243 dbms_output.put_line ('execution time (hsecs)');

44 dbms_output.put_line ('---------------------');

45 dbms_output.put_line ('for loop: ' || to_char (t2 - t1));

46 dbms_output.put_line ('forall: ' || to_char (t3 - t2));

47 end;

48 /

procedure created.

elapsed: 00:00:01.46

sql> exec bulktest;

execution time (hsecs)

---------------------

for loop: 30361

forall: 4792

pl/sql procedure successfully completed.

elapsed: 00:06:32.92

我們可以看到forall較for迴圈效能大大提高。

forall一般用於陣列賦初值。跟do差不多的用法(其實也就是個do)。上個例子就知道了:

forall (i = 1:10, j = 1:10, b(i,j) /= 0.0)

a(i, j) = real(i + j)

b(i, j) = a(i,j) + b(i,j) * real(i*j)

end forall

FORALL與BULKCOLLECT的使用方法

1 使用forall比for效率高,因為前者只切換一次上下文,而後者將是在迴圈次數一樣多個上下文間切換。2 使用bluk collect一次取出乙個資料集合,比用游標條取資料效率高,尤其是在網路不大好的情況下。但bluk collect需要大量記憶體。使用例子 1 定義乙個table create ...

pl sql中的forall簡單測試

之前寫過一篇bulk collect的博文,只是對於bulk collect做了簡單的例項。其實不光是bulk collect,forall對於pl sql的效能的提公升也是相當大的。可以參見下面的兩個圖,可以看到其實在pl sql中,可能很多時候我們所寫的pl sql 會在sql引擎和plsql引...

for迴圈與foreach效能比較與適用場景

for迴圈 for int i 0 i 100 i foreach迴圈 for int i integers 等同於 for iterator i list.iterator i.hasnext 效能上的區別 對於linkedlist,是單鏈表,使用for迴圈每次都要從第乙個元素讀取next域來讀取...