Я пытался выяснить, почему этот скрипт очистки PL / SQL работает медленно для наборов данных, в которых таблица записей содержит несколько сотен тысяч или более записей.Перед выполнением сценария определенное подмножество таблицы записей помечается для очистки - около 75%.
Что вызывает удаление таблицы Record_Part так долго, как в других таблицах?Это потому, что он находится в середине иерархии родитель-потомок с 3 таблицами?Я пропускаю некоторые знания здесь с точки зрения индексов или ограничений?Что я могу сделать, чтобы ускорить этот периодический процесс очистки?
Это база данных Oracle 10g.
Заранее спасибо за чтение моего вопроса.
Схема (частичная):
- Таблица записей является родительской таблицей
- Таблица Record_Part является дочерним элементом Record (запись имеет много записей Record_Part)
- Record_Person является дочерним элементом Record_Part (Record_Part имеет много записей Record_Person)
- Типичное соотношение составляет 1: 7: 9 (запись: record_part: record_person)
Запись
- PK - sysid
- physicalid
- в ожидании
- purge_in_progress
Record_Part
- PK - Part_pk
- FK - record_sysid
Record_Person
Runtime
50000 записей записей
- запись record_person завершается за 1:40 мин
- запись record_part завершается за 1:20 мин
- запись завершается за 10 секунд
300000 записей записей
- запись_персонала завершается за 9 минут
- запись_часть завершается за 2 часа
- запись завершается за 20 минут
2000000 записей записей
- запись record_person завершается за 1 час
- запись record_part завершается за 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;