Wygląda na to, że jest to jeden z obszarów, w których funkcjonalność PL/SQL ewoluowała wraz z wydaniami, w których Oracle wdrażał różne optymalizacje.
Należy zauważyć, że oznacza to również, że niektóre odpowiedzi wymienione w PO są również specyficzne dla wydania, nawet jeśli nie jest to wyraźnie wymienione w tych pytaniach/odpowiedziach. Kiedy minie czas i skończy się korzystanie ze starszych wersji Oracle (ja marzyłem?), informacje te staną się nieaktualne (może to zająć dziesiątki lat).
Powyższy wniosek jest poparty następującym cytatem z rozdziału 12. Dostrajanie aplikacji PL/SQL pod kątem wydajności PL/SQL Language Reference 11g R1 :
Ten problem nie jest już wspomniany w 11g R2 ani 12c R1 wersję dokumentu. Jest to zgodne z ewolucją rozdziału 3 Typy danych PL/SQL.
Odpowiedź:
Od 11gR2 nie ma różnicy w wykorzystaniu pamięci punktu widzenia, aby użyć varchar2(10)
lub varchar2(32767)
. Kompilator Oracle PL/SQL zajmie się brudnymi szczegółami w optymalny sposób!
W przypadku wydań wcześniejszych niż 11gR2 istnieje punkt odcięcia, w którym używane są różne strategie zarządzania pamięcią, co jest jasno udokumentowane w Informacji o języku PL/SQL w każdym wydaniu. .
Powyższe dotyczy tylko zmiennych PL/SQL, gdy nie ma naturalnego ograniczenia długości, które można wyprowadzić z domeny problemu. Jeśli zmienna varchar2 reprezentuje GTIN-14
wtedy należy zadeklarować, że jako varchar2(14)
.
Gdy interfejsy zmiennych PL/SQL z kolumną tabeli używają %type
-attribute, ponieważ jest to bezproblemowy sposób na utrzymanie synchronizacji kodu PL/SQL i struktury bazy danych.
Wyniki testu pamięci:
Przeprowadzam analizę pamięci w Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 z następującymi wynikami:
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
Ponieważ zmiany PGA są identyczne i zależą tylko od iterations
a nie str_size
Dochodzę do wniosku, że zadeklarowany rozmiar varchar2 nie ma znaczenia. Test może być jednak zbyt naiwny - mile widziane komentarze!
Skrypt testowy:
-- 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
Przykład uruchomienia testowego:
$ 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.
$