暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle PL/SQL类型范围和内存使用

askTom 2017-05-24
367

问题描述

考虑在包中使用的一组通用类型定义。

TYPE TYPE_TABN1 IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;

TYPE TYPE_TABV1 IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;

TYPE TYPE_REC1 IS RECORD
(COL1   VARCHAR2(100),
...
COL200 VARCHAR2(100));

TYPE TYPE_TAB1REC1 IS TABLE OF TYPE_REC1 INDEX BY BINARY_INTEGER;

TYPE TYPE_RC1REC1 IS REF CURSOR RETURN TYPE_REC1;
复制


我有几个问题:

1.在哪里定义类型有什么影响?包装规格与。包装主体级别,而不是外部调用的顶级过程。
我们有一个shell脚本对顶层过程的多线程调用,用于基于分区的处理,通常同时调用40个。因此,问题主要是关于同时 (在顶层过程中) 执行40个这些类型定义是否更好,更差或没有不同。

2.对于作为记录表的类型 (例如TYPE_REC1TAB1),如果数据被批量收集 (5000限制) 到该类型的变量中,并且最后100列总是用null “填充”,是否有任何内存影响,而不是只为实际包含数据的前100列定义记录?

谢谢。

专家解答

1.您声明类型的地方只会影响它们可见的范围。如果将它们放在软件包规格中,则可以从其他软件包等中访问它们。在包主体中,只是在包内部编程单元,依此类推。所以它真的归结到你想在其他代码中重用这些代码的位置和方式。

2.我们可以做一个快速测试。让我们创建一个包含101列和1000行的表。仅填充第一列,最后100为null:

declare
  create_tab varchar2(4000);
begin
  create_tab := 'create table t (id int';
  for i in 1 .. 100 loop
    create_tab := create_tab || ', c' || i || ' int';
  end loop;
  create_tab := create_tab || ')';
  execute immediate create_tab;
end;
/
insert into t (id)
  select level from dual connect by level <= 1000;
commit;
复制


我们可以用这个get_stat函数 (HT到Tim Hall) 来测量PGA的使用情况:

create or replace function get_stat (p_stat in varchar2) return number as
  l_return  number;
begin
  select ms.value
  into   l_return
  from   v$mystat ms
  join   v$statname sn
  on     ms.statistic# = sn.statistic#
  and    sn.name = p_stat;
  return l_return;
end get_stat;
/
复制


然后运行两个测试: 批量收集到单个列数组中,一个包含表的所有101列。每次我都会连接到一个新的会话来重置PGA:

conn chris/chris
set serveroutput on
declare
  ids dbms_sql.number_table;
  mem pls_integer;
begin
  mem := get_stat('session pga memory');
  
  select id 
  bulk collect into ids
  from t;
  
  DBMS_OUTPUT.put_line(
    'Just IDs : ' || (get_stat('session pga memory') - mem)
  );
end;
/
Just IDs : 65536

conn chris/chris
set serveroutput on
declare
  type tarr is table of t%rowtype index by binary_integer;
  tab tarr;
  mem pls_integer;
begin
  mem := get_stat('session pga memory');
  
  select * 
  bulk collect into tab
  from t;
  
  DBMS_OUTPUT.put_line(
    'Full table: ' || (get_stat('session pga memory') - mem)
  );
  
end;
/
Full table: 5570560
复制


因此,对于所有列,只有id vs. 5,570,560的内存为65,536字节。记忆多了一个数量级!
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论