Hello! I have read much information about allocation memory for varchar2 as pl\sql variable and column of table.
So now we have memory problem (assign awr report) with a big report. Can u explain please:
1) type StringTable is table of varchar2(32000) index by varchar2; - Do I understand correctly that for index will allocate memory all 32000 b?
2) type map_port_cred is table of rec_port_cred index by varchar2(32767); - in this case for index will be allocate all 32767 memory?
3) 1,2 paragraph does have big influens on memory?
We can test that out easily enough. Let's slowly put more and more rows into an array and take a look at the memory use by the session. I reconnect each time to clear out the session stats
SQL> conn scott/tiger
Connected.
SQL>
SQL> create or replace
2 procedure stats is
3 begin
4 for i in (
5 select s.name, st.value
6 from v$statname s, v$mystat st
7 where st.statistic# = s.statistic#
8 and s.name like 'session pga memory max'
9 )
10 loop
11 dbms_output.put_line(rpad(i.name,40)||lpad(i.value,10));
12 end loop;
13 end;
14 /
Procedure created.
SQL>
SQL> set serverout on
SQL> declare
2 type tlist is table of varchar2(10) index by pls_integer;
3 r tlist;
4 begin
5 for i in 0 .. 10 loop
6 for j in 1 .. 100000 loop
7 r(i*100000+j) := 'xxxxxxxxxx';
8 end loop;
9 stats;
10 end loop;
11 end;
12 /
session pga memory max 9212968
session pga memory max 16290856
session pga memory max 22975528
session pga memory max 29660200
session pga memory max 36344872
session pga memory max 43029544
session pga memory max 49714216
session pga memory max 56398888
session pga memory max 63149096
session pga memory max 69833768
session pga memory max 76518440
PL/SQL procedure successfully completed.
So we ended up with 76MB consumed for our 1,000,000 entries in a varchar2(10) plsql table. Let's now repeat that with varchar2(32767)
SQL>
SQL> conn scott/tiger
Connected.
SQL>
SQL> set serverout on
SQL> declare
2 type tlist is table of varchar2(32767) index by pls_integer;
3 r tlist;
4 begin
5 for i in 0 .. 10 loop
6 for j in 1 .. 100000 loop
7 r(i*100000+j) := 'xxxxxxxxxx';
8 end loop;
9 stats;
10 end loop;
11 end;
12 /
session pga memory max 9147432
session pga memory max 15373352
session pga memory max 22058024
session pga memory max 28742696
session pga memory max 35492904
session pga memory max 42177576
session pga memory max 48862248
session pga memory max 55546920
session pga memory max 62231592
session pga memory max 68916264
session pga memory max 75600936
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL>
Negligible difference. So it's reasonable to conclude that we're using memory as required rather than pre-allocating. In particular, 1000000 * 32k would have been way way more than that. And finally we can look at index by varchar2
SQL> set serverout on
SQL> declare
2 type tlist is table of int index by varchar2(32767);
3 r tlist;
4 begin
5 for i in 0 .. 10 loop
6 for j in 1 .. 100000 loop
7 r(i*100000+j) := 1;
8 end loop;
9 stats;
10 end loop;
11 end;
12 /
session pga memory max 12948520
session pga memory max 23827496
session pga memory max 34772008
session pga memory max 45716520
session pga memory max 56595496
session pga memory max 67540008
session pga memory max 78484520
session pga memory max 89363496
session pga memory max 100308008
session pga memory max 111252520
session pga memory max 122131496
PL/SQL procedure successfully completed.
SQL> set serverout on
SQL> declare
2 type tlist is table of int index by varchar2(20);
3 r tlist;
4 begin
5 for i in 0 .. 10 loop
6 for j in 1 .. 100000 loop
7 r(i*100000+j) := 1;
8 end loop;
9 stats;
10 end loop;
11 end;
12 /
session pga memory max 12948520
session pga memory max 23827496
session pga memory max 34772008
session pga memory max 45716520
session pga memory max 56595496
session pga memory max 67540008
session pga memory max 78484520
session pga memory max 89363496
session pga memory max 100308008
session pga memory max 111252520
session pga memory max 122131496
PL/SQL procedure successfully completed.
So we use memory as required...but as you can see, we *still* do need memory so its unwise to have MASSIVE plsql tables