【发布时间】:2015-08-31 14:59:01
【问题描述】:
我们的 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 分钟,具体取决于大小,并且经常会使我们的存档空间超载。该产品的下一个主要版本将采用“从头开始”的方法来解决问题。下一个次要版本需要保持在数据库中存储的数据范围内。
因此,对于次要版本,我们需要一种可以提高删除性能并且最多需要对数据库进行适度更改的方法。
- REF 分区,但问题是如何?我很想在
Case上做 INTERVAL,在其余部分上做 REF,but that isn't supported。有没有办法通过触发器手动将OptimizationRun分区为CaseId? - 禁用归档/重做日志以进行删除?找不到与此相关的提示。甚至不确定它是否可行。
-
截断?这可能需要一些复杂的表格设置。但也许我没有考虑所有的选择。(每个答案,受打击)
为了帮助说明问题,每个案例的相关数据范围从 15MiB 到 1.5GiB,行数从 20k 到 2M。
更新:当前数据库大小约为 1.5TB。
【问题讨论】:
-
一个设计问题:如果依赖树看起来是
Case -> OptimizationRun -> OptimizationStep,为什么有些表会同时携带这两者?如果使用DELETE CASCADE,您将对那些 12/13 表运行两次删除;一次用于 OptID 键,再次用于 StepID 键!如果其中一个外键没有被索引,性能会更差! -
@Adam Musch:这是一个错误,这些表上只有 1 个键。谢谢你接听!