Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Warum sollte ich nicht alle meine PL/SQL-only VARCHAR2 32767 Bytes machen?

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.

$