Det ser ut som att detta är ett av de områden där PL/SQL-funktionaliteten har utvecklats över releaser när Oracle har implementerat olika optimeringar.
Observera att detta också betyder att några av svaren som listas i OP också är releasespecifika även som inte uttryckligen nämns i dessa frågor/svar. När tiden går och användningen av äldre Oracle-versioner tar slut (jag dagdrömmer?) kommer den informationen att bli föråldrad (kan ta decennier att tänka på).
Slutsatsen ovan stöds av följande citat från kapitel 12 Justera PL/SQL-applikationer för prestanda av PL/SQL Language Reference 11g R1 :
Det här problemet nämns inte längre i 11g R2 inte heller 12c R1 version av dokumentet. Detta är i linje med utvecklingen av kapitel 3 PL/SQL-datatyper.
Svar:
Sedan 11gR2 gör det ingen skillnad från minnesanvändning för att använda varchar2(10)
eller varchar2(32767)
. Oracle PL/SQL-kompilatorn tar hand om de smutsiga detaljerna åt dig på ett optimalt sätt!
För utgåvor före 11gR2 finns det en gränspunkt där olika minneshanteringsstrategier används och detta är tydligt dokumenterat i varje versions PL/SQL Language Reference .
Ovanstående gäller endast för PL/SQL-bara variabler när det inte finns någon naturlig längdbegränsning som kan härledas från problemdomänen. Om en varchar2-variabel representerar ett GTIN-14
då bör man deklarera det som varchar2(14)
.
När PL/SQL-variabel gränssnitt med en tabellkolumn använd %type
-attribut eftersom det är ett sätt utan ansträngning att hålla din PL/SQL-kod och databasstruktur synkroniserad.
Resultat från minnestest:
Jag kör en minnesanalys i Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 med följande resultat:
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
Eftersom PGA-ändringarna är identiska och endast beror på iterations
och inte str_size
Jag drar slutsatsen att den varchar2-deklarerade storleken inte spelar någon roll. Testet kan dock vara för naivt - kommentarer välkomna!
Testskriptet:
-- 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
Testkörningsexempel:
$ 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.
$