使用批量装载SELECT BULK COLLECT INTO 的时候,Oracle会一次性的将结果集装载到PGA中再进行下步操作。如果结果集较大并且OS物理内存紧张的话,可能会导致ORA-4030错误和严重的SWAP.

这时候推荐使用limit 

OWNER   SEGMENT_NAME   SEGMENT_TYPE     size(M)
——- ————– ———-   ——-   ——-   ——-
ORACLE          BIGTABLE             TABLE                  45

测试表有45M

SQL> select PGA_USED_MEM,PGA_ALLOC_MEM,PGA_FREEABLE_MEM,PGA_MAX_MEM from v$process where addr=(XXXX);
PGA_USED_MEM PGA_ALLOC_MEM PGA_FREEABLE_MEM PGA_MAX_MEM
———— ————- —————- ———–
297041        321889                0      321889

SQL> declare
2    type bigtable_a is table of bigtable.owner%type;
3    type bigtable_b is table of bigtable.object_name%type;
4    l_bc_a bigtable_a;
5    l_bc_b bigtable_b;
6  begin
7    select owner, object_name bulk collect into l_bc_a, l_bc_b from bigtable;
8    for i in l_bc_a.first .. l_bc_a.last loop
9      dbms_output.put_line(l_bc_a(i) || ‘, ‘ || l_bc_b(i));
10    end loop;
11  end;
12  /

PL/SQL procedure successfully completed.

SQL>  /
PGA_USED_MEM PGA_ALLOC_MEM PGA_FREEABLE_MEM PGA_MAX_MEM
———— ————- —————- ———–
330921      69520017                0    69520017

导致 PGA_ALLOC_MEM增长69M左右。

使用 limit 限制每次取多少结果集,

SQL> select PGA_USED_MEM,PGA_ALLOC_MEM,PGA_FREEABLE_MEM,PGA_MAX_MEM from v$process where addr=(select paddr from v$session where sid=(select sid from v$Mystat where rownum=1));
PGA_USED_MEM PGA_ALLOC_MEM PGA_FREEABLE_MEM PGA_MAX_MEM
———— ————- —————- ———–
374073        382089                0      382089

SQL> declare
2    type bigtable_a is table of bigtable.owner%type;
3    type bigtable_b is table of bigtable.object_name%type;
4    l_bc_a bigtable_a;
5    l_bc_b bigtable_b;
6
7    cursor cr_rec is
8      select owner, object_name from bigtable;
9  begin
10    open cr_rec;
11    loop
12    fetch cr_rec bulk collect into l_bc_a, l_bc_b limit 200;
13     for i in l_bc_a.first .. l_bc_a.last loop
14      dbms_output.put_line(l_bc_a(i));
15      dbms_output.put_line(l_bc_b(i));
16     end loop;
17    exit when cr_rec%notfound;
18    end loop;
19    close cr_rec;
20  end;
21  /

PL/SQL procedure successfully completed.

SQL>/

PGA_USED_MEM PGA_ALLOC_MEM PGA_FREEABLE_MEM PGA_MAX_MEM
———— ————- —————- ———–
333625        757553                0      757553

避免了内存紧张