Het lijkt erop dat dit een van de gebieden is waar de PL/SQL-functionaliteit is geëvolueerd tijdens releases toen Oracle verschillende optimalisaties heeft geïmplementeerd.
Merk op dat dit ook betekent dat sommige van de antwoorden die in de OP worden vermeld, ook release-specifiek zijn, zelfs als dat niet expliciet wordt vermeld in die vragen/antwoorden. Wanneer de tijd verstrijkt en het gebruik van oudere Oracle-releases eindigt (ik dagdroom?) zal die informatie verouderd zijn (kan tientallen jaren duren).
Bovenstaande conclusie wordt ondersteund door het volgende citaat uit hoofdstuk 12 PL/SQL-applicaties afstemmen op prestaties van PL/SQL-taalreferentie 11g R1 :
Dit probleem wordt niet langer genoemd in 11g R2 noch 12c R1 versie van het document. Dit is in lijn met de evolutie van hoofdstuk 3 PL/SQL-datatypes.
Antwoord:
Sinds 11gR2 maakt het geen verschil uit geheugengebruik oogpunt om varchar2(10)
te gebruiken of varchar2(32767)
. Oracle PL/SQL-compiler zal de vuile details op een optimale manier voor u regelen!
Voor releases vóór 11gR2 is er een afkappunt waar verschillende geheugenbeheerstrategieën worden gebruikt en dit wordt duidelijk gedocumenteerd in de PL/SQL-taalreferentie van elke release. .
Het bovenstaande is alleen van toepassing op PL/SQL-only variabelen als er geen natuurlijke lengtebeperking is die kan worden afgeleid uit het probleemdomein. Als een varchar2-variabele een GTIN-14
vertegenwoordigt dan zou men dat moeten declareren als varchar2(14)
.
Gebruik bij PL/SQL-variabele interfaces met een tabelkolom %type
-attribuut, want dat is de eenvoudige manier om uw PL/SQL-code en databasestructuur synchroon te houden.
Geheugentestresultaten:
Ik voer een geheugenanalyse uit in Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 met de volgende resultaten:
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
Omdat de PGA-wijzigingen identiek zijn en alleen afhankelijk zijn van iterations
en niet str_size
Ik concludeer dat de door varchar2 aangegeven grootte er niet toe doet. De test is misschien te naïef - opmerkingen welkom!
Het testscript:
-- 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
Voorbeeld proefdraaien:
$ 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.
$