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

Oracle 执行高达5百万次的程序

askTom 2017-03-24
219

问题描述

你好,

我在我的架构中表示以下表格:

容器: 包含一个列ContainerName (唯一),并表示一个容器
Container_Item: 包含一个列ContainerItemName (唯一),并表示一个容器项
Container_canitidates: 此表包含 “容器” 和 “Container_Item” 表之间的链接。每个 “容器” 可以包含任意数量的 “容器项目” (甚至位于另一个 “容器” 中的 “容器项目”)
Elements: 包含表示元素的列ElementName (唯一)。
化合物: 此表包含 “ContainerItem” 和 “Elements” 表之间的链接。每个 “ContainerItem” 可以包含任意数量的 “元素” (甚至位于另一个ContainerItem中的 “元素”)

当我添加一个新的容器我执行以下操作:
1) 在 “容器” 表中创建插入
2) 使用过程插入container_item:
* 检查container_item名称是否存在。如果存在,获取它的id并在 “container_canddates” 表中使用它
* 如果container_item名称不存在,请创建它并在 “container_canditidates” 表中使用生成的id
3) 使用一个过程插入一个元素
* 检查元素名称是否存在。如果存在,获取其id并在 “化合物” 表中使用
* 如果元素名称不存在,请创建它并在 “化合物” 表中使用生成的id

我在事务中执行上三个操作。

这适用于较小的结构,但是如果我有一个包含5.000项的容器,并且每个项可以包含1.000唯一的元素,我最终得到了上面描述的约5.000.000操作 (1-3) 的事务。这真的很耗时,非内存友好,也不是用户友好的。

另外,当我删除整个结构时,我必须检查另一个容器/container_item未使用哪些内部元素 (元素,container_items)。我使用一些光标执行此操作。同样,我的代码工作,但它不是很有效。

您能给我这样的想法如何使用上面描述的表结构实现大型结构的添加/更新/删除操作。我也想拥有使用交易的好处。

谢谢。


专家解答

只要您使用的是数组操作,那么您可以获得与1行相似的许多行性能级别。

例如,对于插入,在此示例中,我们插入1行,100行,然后1000行:

SQL> create table t1 ( x1 int );

Table created.

SQL>
SQL> create or replace
  2  type numlist is table of number;
  3  /

Type created.

SQL>
SQL> set serverout on
SQL> declare
  2    n numlist := numlist();
  3    s timestamp;
  4  begin
  5    n.extend(1);
  6    n(1) := 10;
  7
  8    s := localtimestamp;
  9    insert into t1
 10    select column_value
 11    from table(n);
 12    dbms_output.put_line(localtimestamp-s);
 13
 14    for i in 2 .. 100 loop
 15      n.extend;
 16      n(i) := i;
 17    end loop;
 18
 19    s := localtimestamp;
 20    insert into t1
 21    select column_value
 22    from table(n);
 23    dbms_output.put_line(localtimestamp-s);
 24
 25    for i in 101 .. 1000 loop
 26      n.extend;
 27      n(i) := i;
 28    end loop;
 29
 30    s := localtimestamp;
 31    insert into t1
 32    select column_value
 33    from table(n);
 34    dbms_output.put_line(localtimestamp-s);
 35
 36  end;
 37  /
+000000000 00:00:00.003000000
+000000000 00:00:00.001000000
+000000000 00:00:00.000000000

PL/SQL procedure successfully completed.

SQL> select count(*) from t1;

  COUNT(*)
----------
      1101

1 row selected.

SQL>
复制


您可以看到经过的时间是如此之快,即使对于1000行。

所以对这些东西使用数组操作。对于更新和删除,您也可以使用SQL操作,或者也可以考虑从PL/SQL进行FORALL操作。AskTom上有很多FORALL的例子。

所以不要执行proc 5000时间... 5000行 * 一次 *。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论