oracle - 提高 Oracle DELETE 性能的策略

标签 oracle oracle11g

我们的 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 不等。

    更新: DB 的当前大小约为 1.5TB。

    最佳答案

    删除数据对于数据库来说是一项艰巨的工作。它必须先创建镜像、更新索引、写入重做日志并删除数据。这是一个缓慢的过程。如果您可以有一个窗口来执行此任务,最简单和最快的方法是构建包含所需数据的新表。删除旧表并重命名新表。
    这需要一些设置工作,这是显而易见的,但很可能做到。
    不那么激烈的一步是在删除之前删除索引。我的投票将投给 CTAS(根据选择创建表)并构建新表。
    一个好的分区模式肯定会有帮助,也许在下一个版本中 Oracle 可以结合区间和引用分区。拥有它会非常好。

    禁用日志记录 .... 无法删除,但 CTAS 可以使用 nologging。准备好后进行备份,并确保将数据文件传输到备用数据库(如果有)。

    关于oracle - 提高 Oracle DELETE 性能的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5792425/

    相关文章:

    sql - 加入两个具有 where 子句的选择查询

    sql - 如何使用分层子查询构建层次结构路径

    sql - oracle中两个时间戳之间的差异(以天为单位)

    java - 如何在 Java 中获取可滚动的结果集

    java - 如何在Java中注册Raw类型的OutParameter

    c# - 如何在使用托管 ODP.NET 时从 C# 查询 LDAP 以解析 Oracle TNS 主机名?

    sql - 如何插入表列值: month & day from column datetype

    sql - 使用数据库链接调用oracle函数

    mysql - SQL 查询,难以使用 COUNT() 计算实例/出现次数

    java - 是否可以将 rowtype 表从 java 传递到 oracle 存储过程?