Oracle
 sql >> Base de données >  >> RDS >> Oracle

Pourquoi ne devrais-je pas faire tous mes octets VARCHAR2 PL/SQL uniquement 32767 ?

Il semble que ce soit l'un des domaines dans lesquels la fonctionnalité PL/SQL a évolué au fil des versions lorsqu'Oracle a mis en œuvre différentes optimisations.

Notez que cela signifie également que certaines des réponses répertoriées dans l'OP sont également spécifiques à la version, même si elles ne sont pas explicitement mentionnées dans ces questions/réponses. Lorsque le temps passera et que l'utilisation d'anciennes versions d'Oracle prendra fin (je rêve éveillé ?), ces informations deviendront obsolètes (cela pourrait prendre des décennies à réfléchir).

La conclusion ci-dessus est étayée par la citation du chapitre 12 Régler les performances des applications PL/SQL de PL/SQL Language Reference 11g R1 :

Ce problème n'est plus mentionné dans 11g R2 ni 12c R1 version du document. Ceci est conforme à l'évolution du chapitre 3 Types de données PL/SQL.

Réponse :

Depuis 11gR2, cela ne fait aucune différence avec l'utilisation de la mémoire de point de vue à utiliser varchar2(10) ou varchar2(32767) . Le compilateur Oracle PL/SQL s'occupera des détails sales pour vous de manière optimale !

Pour les versions antérieures à 11gR2, il existe un point limite où différentes stratégies de gestion de la mémoire sont utilisées et cela est clairement documenté dans la référence du langage PL/SQL de chaque version. .

Ce qui précède ne s'applique qu'aux variables PL/SQL uniquement lorsqu'il n'y a pas de restriction de longueur naturelle pouvant être dérivée du domaine problématique. Si une variable varchar2 représente un GTIN-14 alors on devrait déclarer cela comme varchar2(14) .

Lorsque la variable PL/SQL s'interface avec une colonne de table, utilisez %type -attribut car c'est le moyen sans effort de synchroniser votre code PL/SQL et votre structure de base de données.

Résultats du test de mémoire :

J'exécute une analyse de la mémoire dans Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 avec les résultats suivants :

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

Parce que les changements PGA sont identiques et ne dépendent que des iterations et non str_size Je conclus que la taille déclarée par varchar2 n'a pas d'importance. Le test est peut-être trop naïf - commentaires bienvenus !

Le script de test :

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

Exemple de test :

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

$