这是Strategy提高Oracle DELETE性能的后续问题.回顾一下,我们有一个大型DB,其中包含表示来自优化系统的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 */
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一种分区Case
数据的方法,这样我就可以删除与案例相关的分区来删除它的数据.理想情况下,OptimizationRun
会有一个基于的间隔分区CaseId
,这会过滤到它的子节点.但是,11g不支持INTERVAL和REF分区的组合.
我相当肯定基于数据库大小和表空间在ASSM中的要求,ENABLE ROW MOVEMENT是不可能的.可能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;
Run Code Online (Sandbox Code Playgroud)
然后删除之前的必要触发器:
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;
Run Code Online (Sandbox Code Playgroud)
好主意?或者这是SNL Bad Idea Jeans商业广告中的一个想法吗?
更新,尺寸参考:
我非常确定您使用分区来解决删除性能问题的方法是正确的。但是,我认为您无法将其与触发器混合使用。带有触发器的复杂逻辑一直困扰着我,但除此之外,您可能会遇到以下问题:
处理删除和创建分区的过程会更容易编码和维护,例如:
CREATE PROCEDURE add_case (case_id, ...) AS
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE OptimizationRun ADD partition...';
/* repeat for each child table */
INSERT INTO Case VALUES (...);
END;
Run Code Online (Sandbox Code Playgroud)
关于删除分区,您必须检查这是否适用于引用完整性。在删除父子表关系中的父表分区之前,可能需要禁用外键约束。
另请注意,分区删除后全局索引将处于不可用状态。除非您在 drop 语句中指定 UPDATE GLOBAL ,否则您必须重建它们(显然这会自动重建它们,但会花费更多时间)。
归档时间: |
|
查看次数: |
6019 次 |
最近记录: |