Это следующий вопрос к Стратегии повышения производительности Oracle DELETE . Напомним, у нас есть большая БД с иерархией таблиц, представляющих выходные данные от 1D до 4D из системы оптимизации. Чтение и запись этих данных происходит быстро и обеспечивает удобные средства для наших различных систем для использования информации.
Однако удаление неиспользуемых данных превратилось в медвежью услугу. Текущая иерархия таблиц приведена ниже.
/* Metadata tables */
Case(CaseId, DeleteFlag, ...) On Delete Cascade CaseId
OptimizationRun(OptId, CaseId, ...) On Delete Cascade OptId
OptimizationStep(StepId, OptId, ...) On Delete Cascade StepId
/* Data tables */
Files(FileId, CaseId, Blob) /* deletes are near instantateous here */
/* Data per run */
OnedDataX(OptId, ...)
TwoDDataY1(OptId, ...) /* packed representation of a 1D slice */
/* Data not only per run, but per step */
TwoDDataY2(StepId, ...) /* packed representation of a 1D slice */
ThreeDDataZ(StepId, ...) /* packed representation of a 2D slice */
FourDDataZ(StepId, ...) /* packed representation of a 3D slice */
/* ... About 10 or so of these tables exist */
Я ищу средство разделения данных Case
, чтобы я мог отбросить раздел, относящийся к делу, чтобы удалить его данные. В идеале OptimizationRun
должен иметь интервальное разделение, основанное на CaseId
, и оно будет отфильтровываться до его дочерних элементов. Однако 11g не поддерживает комбинацию секционирования INTERVAL и REF.
Я вполне уверен, что ВКЛЮЧИТЬ ПЕРЕМЕЩЕНИЕ СТРОК не может быть и речи, исходя из размера БД и требования, чтобы табличные пространства размещались в ASSM. Может быть, разделение RANGE на OptimizationRun
и разделение REF на остальных?
Я предполагаю, что с этой стратегией мне понадобится триггер, который выполняет что-то вроде следующего:
CREATE OR REPLACE TRIGGER Case_BeforeInsert_MakePartitions
BEFORE INSERT
ON Case
FOR EACH ROW
DECLARE
v_PartName varchar(64) := 'CASE_OPTPART_' || :new.CaseId;
v_PartRange Case.CaseId%type := :new.CaseId
BEGIN
-- Take :new.CaseId and create the partition
ALTER TABLE OptimizationRun
ADD PARTITION v_PartName
VALUES LESS THAN ( v_PartRange );
END;
И затем необходимый триггер для перед удалением :
CREATE OR REPLACE TRIGGER Case_BeforeDelete_RemovePartitions
BEFORE DELETE
ON Case
FOR EACH ROW
DECLARE
v_PartName varchar(64) := 'CASE_OPTPART_' || :old.CaseId;
BEGIN
-- Drop the partitions associated with the case
ALTER TABLE OptimizationRun
DROP PARTITION v_PartName;
END;
Хорошая идея? Или это идея из рекламного ролика SNL Bad Idea Jeans?
Обновление, ссылка на размер :