当Oracle实施不同的优化时,看起来这是PL / SQL功能在版本上发展的领域之一。
请注意,这也意味着OP中列出的一些答案也是特定于发布的,即使这些问题/答案中没有明确提及。 当时间过去并使用较旧的Oracle版本结束时(我在做白日梦?),这些信息将会过时(可能需要几十年的时间)。
上面的结论得到以下引用的支持:第12章调整 PL / SQL语言参考11g R1的 PL / SQL应用程序 :
声明4000个或更多字符的VARCHAR2变量
当您不确定表达式结果有多大时,可能需要分配大型VARCHAR2变量。 您可以通过声明大尺寸的VARCHAR2变量(例如32000)来节省内存,而不是估计高端的一些变量,例如通过指定256或1000. PL / SQL具有一个优化,可以轻松避免溢出问题和仍然保存记忆。 为VARCHAR2变量指定大于4000个字符的大小; PL / SQL等待您分配变量,然后根据需要分配尽可能多的存储空间。
在11g R2和12c R1版本的文档中不再提及此问题。 这与第3章PL / SQL数据类型的演变一致。
回答:
从11gR2开始,它与使用varchar2(10)或varchar2(32767) 内存使用没有区别。 Oracle PL / SQL编译器将以最佳方式为您处理脏信息!
对于11gR2之前的版本,有一个截止点,使用不同的内存管理策略,每个版本的PL / SQL语言参考中都清楚地记录了这一点。
当没有可以从问题域派生的自然长度限制时,上述内容仅适用于PL / SQL专用变量。 如果varchar2变量代表GTIN-14,那么应该将其声明为varchar2(14) 。
当带有表列的PL / SQL变量接口使用%type -attribute时,这是使PL / SQL代码和数据库结构保持同步的零工作方式。
记忆测试结果:
我在Oracle Database 11g企业版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 @memory-test.sql 32767 10000
Change in UGA memory: 65488 (Current = 1927304)
Change in PGA memory: 655360 (Current = 3572704)
PL/SQL procedure successfully completed.
$