Det ser ud til, at dette er et af de områder, hvor PL/SQL-funktionaliteten har udviklet sig over udgivelser, når Oracle har implementeret forskellige optimeringer.
Bemærk, at dette også betyder, at nogle af svarene, der er anført i OP'et, også er udgivelsesspecifikke, selvom det ikke er eksplicit nævnt i disse spørgsmål/svar. Når tiden går, og brugen af ældre Oracle-udgivelser slutter (dagdrømmer jeg?), vil den information blive forældet (kan tage årtier eftertanke).
Konklusionen ovenfor understøttes af følgende citat fra kapitel 12 Tuning af PL/SQL-applikationer til ydeevne af PL/SQL Language Reference 11g R1 :
Dette problem er ikke længere nævnt i 11g R2 heller ikke 12c R1 version af dokumentet. Dette er i tråd med udviklingen af kapitel 3 PL/SQL-datatyper.
Svar:
Siden 11gR2 gør det ingen forskel fra brug af hukommelse synspunkt at bruge varchar2(10)
eller varchar2(32767)
. Oracle PL/SQL compiler vil tage sig af de beskidte detaljer for dig på en optimal måde!
For udgivelser før 11gR2 er der et cutoff-punkt, hvor forskellige hukommelseshåndteringsstrategier bruges, og dette er tydeligt dokumenteret i hver udgivelses PL/SQL sprogreference .
Ovenstående gælder kun for PL/SQL-only variabler, når der ikke er nogen naturlig længdebegrænsning, der kan udledes fra problemdomænet. Hvis en varchar2-variabel repræsenterer et GTIN-14
så skal man erklære det som varchar2(14)
.
Når PL/SQL-variable grænseflader med en tabelkolonne, skal du bruge %type
-attribut, da det er en nul-indsats måde at holde din PL/SQL-kode og databasestruktur synkroniseret.
Hukommelsestestresultater:
Jeg kører en hukommelsesanalyse i Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 med følgende resultater:
str_size iterations UGA PGA
-------- ---------- ----- ------
10 100 65488 0
10 1000 65488 65536
10 10000 65488 655360
32767 100 65488 0
32767 1000 65488 65536
32767 10000 65488 655360
Fordi PGA-ændringerne er identiske og kun afhænger af iterations
og ikke str_size
Jeg konkluderer, at den varchar2 erklærede størrelse ikke betyder noget. Testen kan dog være for naiv - kommentarer modtages gerne!
Testscriptet:
-- plsql_memory is a convenience package wrapping sys.v_$mystat s and
-- sys.v_$statname tables written by Steven Feuerstein and available in the
-- code-zip file accompanying his book.
set verify off
define str_size=&1
define iterations=&2
declare
type str_list_t is table of varchar2(&str_size);
begin
plsql_memory.start_analysis;
declare
v_strs str_list_t := str_list_t();
begin
for i in 1 .. &iterations
loop
v_strs.extend;
v_strs(i) := rpad(to_char(i), 10, to_char(i));
end loop;
plsql_memory.show_memory_usage;
end;
end;
/
exit
Eksempel på testkørsel:
$ sqlplus -SL <CONNECT_STR> @memory-test.sql 32767 10000
Change in UGA memory: 65488 (Current = 1927304)
Change in PGA memory: 655360 (Current = 3572704)
PL/SQL procedure successfully completed.
$