Oracle
 sql >> Database >  >> RDS >> Oracle

Perché non dovrei creare tutti i miei VARCHAR2 32767 byte solo PL/SQL?

Sembra che questa sia una delle aree in cui la funzionalità PL/SQL si è evoluta rispetto alle versioni quando Oracle ha implementato diverse ottimizzazioni.

Nota che questo significa anche che alcune delle risposte elencate nell'OP sono specifiche per il rilascio anche se non sono esplicitamente menzionate in quelle domande/risposte. Quando il tempo passerà e l'uso delle versioni precedenti di Oracle finirà (io sto sognando ad occhi aperti?) le informazioni diventeranno obsolete (potrebbero volerci decenni).

La conclusione di cui sopra è supportata dalla seguente citazione dal capitolo 12 Ottimizzazione delle applicazioni PL/SQL per le prestazioni di Riferimento al linguaggio PL/SQL 11g R1 :

Questo problema non è più menzionato in 11g R212c R1 versione del documento. Ciò è in linea con l'evoluzione del capitolo 3 Tipi di dati PL/SQL.

Risposta:

Dal momento che 11gR2 non fa differenza dall'uso della memoria punto di vista per utilizzare varchar2(10) o varchar2(32767) . Il compilatore Oracle PL/SQL si prenderà cura dei dettagli sporchi per te in modo ottimale!

Per le versioni precedenti alla 11gR2 esiste un punto di interruzione in cui vengono utilizzate diverse strategie di gestione della memoria e questo è chiaramente documentato in PL/SQL Language Reference di ciascuna versione .

Quanto sopra si applica solo alle variabili PL/SQL solo quando non esiste alcuna restrizione di lunghezza naturale che può essere derivata dal dominio del problema. Se una variabile varchar2 rappresenta un GTIN-14 quindi si dovrebbe dichiararlo come varchar2(14) .

Quando le interfacce di variabili PL/SQL con una colonna di tabella usano %type -attributo in quanto questo è il modo senza sforzo per mantenere sincronizzati il ​​codice PL/SQL e la struttura del database.

Risultati del test di memoria:

Eseguo un'analisi della memoria in Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 con i seguenti risultati:

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

Perché le modifiche PGA sono identiche e dipendono solo da iterations e non str_size Concludo che la dimensione dichiarata di varchar2 non ha importanza. Il test potrebbe essere troppo ingenuo però - commenti benvenuti!

Lo script di prova:

-- 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

Esempio di esecuzione di prova:

$ 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.

$