问题描述
你好,
我在我的架构中表示以下表格:
容器: 包含一个列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)。我使用一些光标执行此操作。同样,我的代码工作,但它不是很有效。
您能给我这样的想法如何使用上面描述的表结构实现大型结构的添加/更新/删除操作。我也想拥有使用交易的好处。
谢谢。
我在我的架构中表示以下表格:
容器: 包含一个列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行:
您可以看到经过的时间是如此之快,即使对于1000行。
所以对这些东西使用数组操作。对于更新和删除,您也可以使用SQL操作,或者也可以考虑从PL/SQL进行FORALL操作。AskTom上有很多FORALL的例子。
所以不要执行proc 5000时间... 5000行 * 一次 *。
例如,对于插入,在此示例中,我们插入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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC ASM 磁盘组满了,无法扩容怎么在线处理?
Lucifer三思而后行
986次阅读
2025-03-17 11:33:53
Oracle DataGuard高可用性解决方案详解
孙莹
426次阅读
2025-03-26 23:27:33
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
383次阅读
2025-04-15 17:24:06
墨天轮个人数说知识点合集
JiekeXu
363次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
357次阅读
2025-04-08 09:12:48
Oracle SQL 执行计划分析与优化指南
Digital Observer
326次阅读
2025-04-01 11:08:44
Oracle 19c RAC更换IP实战,运维必看!
szrsu
294次阅读
2025-04-08 23:57:08
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
292次阅读
2025-03-24 09:42:53
切换Oracle归档路径后,不能正常删除原归档路径上的归档文件
dbaking
287次阅读
2025-03-19 14:41:51
oracle定时任务常用攻略
virvle
286次阅读
2025-03-25 16:05:19