Parece que esta é uma das áreas em que a funcionalidade PL/SQL evoluiu ao longo das versões quando a Oracle implementou otimizações diferentes.
Observe que isso também significa que algumas das respostas listadas no OP também são específicas da versão, mesmo que não sejam explicitamente mencionadas nessas perguntas/respostas. Quando o tempo passar e o uso de versões mais antigas do Oracle terminar (eu sonhando acordado?) essas informações ficarão desatualizadas (pode levar décadas).
A conclusão acima é apoiada pela seguinte cotação do capítulo 12 Ajustando aplicativos PL/SQL para desempenho da Referência da Linguagem PL/SQL 11g R1 :
Esse problema não é mais mencionado em 11g R2 nem 12c R1 versão do documento. Isso está de acordo com a evolução do capítulo 3 Tipos de dados PL/SQL.
Resposta:
Desde 11gR2 não faz diferença para uso de memória ponto de vista para usar
varchar2(10)
ou varchar2(32767)
. O compilador Oracle PL/SQL cuidará dos detalhes sujos para você de maneira otimizada! Para versões anteriores a 11gR2, há um ponto de corte em que diferentes estratégias de gerenciamento de memória são usadas e isso está claramente documentado na Referência de linguagem PL/SQL de cada versão .
O acima só se aplica a variáveis somente PL/SQL quando não há restrição de comprimento natural que possa ser derivada do domínio do problema. Se uma variável varchar2 representa um GTIN-14 então deve-se declarar isso como
varchar2(14)
. Quando interfaces de variável PL/SQL com uma coluna de tabela usam
%type
-attribute, pois essa é a maneira de esforço zero para manter o código PL/SQL e a estrutura do banco de dados em sincronia. Resultados do teste de memória:
Eu executo uma análise de memória no Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 com os seguintes resultados:
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
Como as alterações do PGA são idênticas e dependem apenas de
iterations
e não str_size
Concluo que o tamanho declarado do varchar2 não importa. O teste pode ser muito ingênuo - comentários são bem-vindos! O roteiro de teste:
-- 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
Exemplo de execução de teste:
$ 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.
$