Изглежда, че това е една от областите, в които функционалността на PL/SQL се е развила през версиите, когато Oracle е внедрил различни оптимизации.
Обърнете внимание, че това също означава, че някои от отговорите, изброени в OP, също са специфични за изданието, дори това да не е изрично споменато в тези въпроси/отговори. Когато времето изтече и използването на по-стари версии на Oracle приключи (мечтая ли?), тази информация ще стане остаряла (може да отнеме десетилетия на размисъл).
Заключението по-горе е подкрепено със следния цитат от глава 12 Настройване на PL/SQL приложения за производителност на PL/SQL Language Reference 11g R1 :
Този проблем вече не се споменава в 11g R2 нито 12c R1 версия на документа. Това е в съответствие с еволюцията на глава 3 PL/SQL типове данни.
Отговор:
От 11gR2 няма разлика от използването на памет от гледна точка за използване на varchar2(10)
или varchar2(32767)
. Компилаторът Oracle PL/SQL ще се погрижи за мръсните детайли вместо вас по оптимален начин!
За издания преди 11gR2 има гранична точка, при която се използват различни стратегии за управление на паметта и това е ясно документирано във всяка версия PL/SQL Language Reference .
Горното се отнася само за променливи само за PL/SQL, когато няма естествено ограничение на дължината, което може да бъде извлечено от проблемния домейн. Ако променлива varchar2 представлява GTIN-14
тогава трябва да декларирате това като varchar2(14)
.
Когато PL/SQL-променлива се свързва с колона на таблица, използвайте %type
-attribute, тъй като това е начинът с нулево усилие да поддържате PL/SQL кода и структурата на базата данни в синхрон.
Резултати от теста на паметта:
Изпълнявам анализ на паметта в Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 със следните резултати:
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
Тъй като промените на PGA са идентични и зависят само от iterations
а не str_size
Заключавам, че декларираният размер на varchar2 няма значение. Тестът обаче може да е твърде наивен - коментарите са добре дошли!
Тестовият скрипт:
-- 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
Пример за тестово изпълнение:
$ 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.
$