我们的 Oracle 11g 安装开始变得越来越大。该数据库是在集群上运行的并行优化系统的后端。流程的输入与优化步骤的输出一起包含在数据库中。输入包括死记硬背的配置数据和一些二进制文件(使用 11g 的 SecureFiles)。输出包括当前存储在 DB 中的 1D、2D、3D 和 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 */
收割者脚本每天都会出现,并使用
DeleteFlag = 1
查找案例。并继续 DELETE FROM Case WHERE DeleteFlag = 1
,允许级联继续。这种策略非常适合读/写,但现在在我们想要清除数据时超出了我们的能力!问题是删除一个案例需要大约 20-40 分钟,具体取决于大小,并且经常使我们的存档空间过载。该产品的下一个主要版本将采用“从头开始”的方法来解决问题。下一个次要版本需要保持在数据库中存储的数据范围内。
因此,对于次要版本,我们需要一种可以提高删除性能并且最多需要对数据库进行适度更改的方法。
Case
上做 INTERVAL和 REF 其余部分,but that isn't supported .有没有办法手动分区OptimizationRun
来自 CaseId
通过触发器? 为了帮助说明这个问题,每个案例的相关数据范围从 15MiB 到 1.5GiB,行数从 20k 到 2M 不等。
更新: DB 的当前大小约为 1.5TB。
最佳答案
删除数据对于数据库来说是一项艰巨的工作。它必须先创建镜像、更新索引、写入重做日志并删除数据。这是一个缓慢的过程。如果您可以有一个窗口来执行此任务,最简单和最快的方法是构建包含所需数据的新表。删除旧表并重命名新表。
这需要一些设置工作,这是显而易见的,但很可能做到。
不那么激烈的一步是在删除之前删除索引。我的投票将投给 CTAS(根据选择创建表)并构建新表。
一个好的分区模式肯定会有帮助,也许在下一个版本中 Oracle 可以结合区间和引用分区。拥有它会非常好。
禁用日志记录 .... 无法删除,但 CTAS 可以使用 nologging。准备好后进行备份,并确保将数据文件传输到备用数据库(如果有)。
关于oracle - 提高 Oracle DELETE 性能的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5792425/