Es sieht so aus, als ob dies einer der Bereiche ist, in denen sich die PL/SQL-Funktionalität im Laufe der Versionen weiterentwickelt hat, als Oracle verschiedene Optimierungen implementiert hat.
Beachten Sie, dass dies auch bedeutet, dass einige der im OP aufgeführten Antworten auch releasespezifisch sind, auch wenn dies in diesen Fragen/Antworten nicht ausdrücklich erwähnt wird. Wenn die Zeit vergeht und die Verwendung älterer Oracle-Versionen endet (ich träume davon?), werden diese Informationen veraltet sein (könnte Jahrzehnte dauern).
Die obige Schlussfolgerung wird durch das folgende Zitat aus Kapitel 12 Optimieren der Leistung von PL/SQL-Anwendungen von PL/SQL-Sprachreferenz 11g R1 :
Dieses Problem wird in 11g R2 noch 12c R1 Version des Dokuments. Dies steht im Einklang mit der Entwicklung des Kapitels 3 PL/SQL-Datentypen.
Antwort:
Seit 11gR2 macht es keinen Unterschied zur Speichernutzung Gesichtspunkt, um varchar2(10)
zu verwenden oder varchar2(32767)
. Der Oracle PL/SQL-Compiler kümmert sich optimal um die schmutzigen Details!
Für Versionen vor 11gR2 gibt es einen Grenzpunkt, an dem unterschiedliche Speicherverwaltungsstrategien verwendet werden, und dies ist in der PL/SQL-Sprachreferenz jeder Version klar dokumentiert .
Das Obige gilt nur für reine PL/SQL-Variablen, wenn es keine natürliche Längenbeschränkung gibt, die aus der Problemdomäne abgeleitet werden kann. Wenn eine varchar2-Variable eine GTIN-14
darstellt dann sollte man das als varchar2(14)
deklarieren .
Wenn eine PL/SQL-Variable mit einer Tabellenspalte interagiert, verwenden Sie %type
-Attribut, da dies der mühelose Weg ist, Ihren PL/SQL-Code und Ihre Datenbankstruktur synchron zu halten.
Ergebnisse des Gedächtnistests:
Ich führe eine Speicheranalyse in Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 mit den folgenden Ergebnissen durch:
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
Weil die PGA-Änderungen identisch sind und nur von iterations
abhängen und nicht str_size
Ich schließe daraus, dass die von varchar2 deklarierte Größe keine Rolle spielt. Der Test könnte aber zu naiv sein - Kommentare willkommen !
Das Testskript:
-- 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
Beispiel für einen Testlauf:
$ 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.
$