这是针对Strategy to improve Oracle DELETE performance的后续问题。回顾一下,我们有一个大型数据库,其中包含表示层次结构的表示来自优化系统的1D到4D输出数据。读取和写入这些数据的速度非常快,并为我们各种系统利用这些信息提供了一个便利的途径。用于DELETE性能问题的Oracle分区解决方案
但是,删除未使用的数据已成为一个熊。当前表层次结构如下。
/* 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分区的组合。
我很确定ENABLE ROW MOVEMENT基于数据库大小以及表空间生活在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商业广告中的一个想法吗?
更新,大小的参考:
- 1D数据表〜1.7G
- 2D数据表〜12.5G
- 三维数据表〜117.3G
- 4D数据表〜315.2 G
如何在删除标记? (它是什么逻辑)。基于一个日期也许? (老化记录)。还有别的吗?这可能有助于推导出最佳方法 – tbone 2011-04-27 19:46:06
'DeleteFlag'由用户设置,这会导致触发器应用'SYSDATE + 14'的'DeleteDate',以防用户想要撤销其决定。 – user7116 2011-04-27 20:34:33