這是針對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