gpt4 book ai didi

plsql - 为什么 PL/SQL 批量 DML 对于具有父子约束表的大型数据集运行速度变慢?

转载 作者:行者123 更新时间:2023-12-01 09:15:28 26 4
gpt4 key购买 nike

我一直在试图弄清楚为什么这个 PL/SQL 清除脚本对于记录表有几十万或更多记录的数据集运行缓慢。在脚本执行之前,记录表的某个子集被标记为要清除 - 大约 75%。

是什么导致 Record_Part 表的删除时间比其他表长得多?是不是因为在3表父子层级的中间?就索引或约束而言,我在这里是否遗漏了一些知识?我可以做些什么来加快这个定期清除过程?

这是一个 Oracle 10g 数据库。

提前感谢您阅读我的问题。

架构(部分):

  • 记录表是父表
  • Record_Part 表是 Record 的子表(Record 有很多 Record_Part)
  • Record_Person 是 Record_Part 的 child (Record_Part 有很多 Record_Person)
  • 典型比例为 1:7:9(记录:记录部分:记录人)

记录

  • PK - 系统标识
  • 物理编号
  • 待定
  • purge_in_progress

记录部分

  • PK - Part_pk
  • FK - record_sysid

记录人

  • PK - 系统标识
  • FK - Part_pk

运行时

50000条记录

  • record_person forall 在 1 分 40 分钟内完成
  • record_part forall 在 1 分 20 分钟内完成
  • 所有记录在 10 秒内完成

300000条记录

  • record_person forall 在 9 分钟内完成
  • record_part forall 在 2 小时内完成
  • 记录所有在 20 分钟内完成的记录

2000000条记录

  • record_person forall 在 1 内完成小时
  • record_part forall 在 13 内完成小时 (!)
  • 8 分钟内全部完成的记录

索引和约束 DDL

alter table Record add constraint record_REC_PK primary key (SYSID) using index tablespace DB_INDEX1;
alter table Record_Part add constraint RECPART_REC_PK primary key (Part_PK) using index tablespace DB_INDEX1;
alter table Record_Part add constraint RECPART_FK foreign key (RECORD_SYSID) references record (SYSID);
alter table Record_Person add constraint RECPERSON_REC_PK primary key (SYSID) using index tablespace DB_INDEX1;
alter table Record_Person add constraint RECPERSON_FK foreign key (Part_PK) references Record_Part (Part_PK);

CREATE INDEX REC_PURGE_IDX ON record (PURGE_IN_PROGRESS);
CREATE INDEX REC_PHYSID_IDX ON record (PHYSICALID);
CREATE INDEX REC_PENDING_IDX ON record (PENDING);
CREATE INDEX RECPART_RECORD_SYSID_IDX ON Record_Part (RECORD_SYSID);
CREATE INDEX RECPERSON_PARTPK_IDX on Record_Person (PART_PK);

脚本:(下面的脚本中省略了时间戳打印)

DECLARE

TYPE sSysid IS TABLE OF record.sysid%TYPE
INDEX BY PLS_INTEGER;

TYPE physicalid IS TABLE OF record.physicalid%TYPE
INDEX BY PLS_INTEGER;

l_sid sSysid;
l_physicalid physicalid;

BEGIN
SELECT sysid, physicalid
BULK COLLECT INTO l_sid, l_physicalid
FROM record
where purge_in_progress = 1;

FORALL i IN l_sid.FIRST .. l_sid.LAST
delete from record_person where Part_pk like concat(l_sid(i), '%') or Part_pk like concat(l_physicalid(i), '%');

commit;

FORALL i IN l_sid.FIRST .. l_sid.LAST
delete from record_Part where record_sysid = l_sid(i);

commit;

FORALL i IN l_sid.FIRST .. l_sid.LAST
delete from record where sysid = l_sid(i);

END;
/

commit;

最佳答案

查看此线程上的第一个回复。正如 Justin 指出的那样,您需要使用 limit 子句来获取固定数量的记录(通常使用 100 条,您可以对其进行参数化并查看适合您的情况)。

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::p11_question_id:5918938803188

关于plsql - 为什么 PL/SQL 批量 DML 对于具有父子约束表的大型数据集运行速度变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5277593/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com