Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Dlaczego nie powinienem zrobić wszystkich 32767 bajtów VARCHAR2 tylko dla PL/SQL?

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.

$


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-06502:PL/SQL:błąd liczbowy lub wartości:zbyt mały bufor ciągu znaków

  2. Jak sprawdzić maksymalną liczbę dozwolonych połączeń z bazą danych Oracle?

  3. Wybór minimalnej różnicy między dwiema datami w Oracle, gdy daty są reprezentowane jako znaczniki czasu UNIX

  4. jak przekazać zmienną ze skryptu powłoki do sqlplus

  5. Tworzenie wyzwalacza generującego wartość kolumny ID przed wstawieniem, gdy tworzone są nowe tabele