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