我们的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
和其他地方的REF but that isn't supported上进行INTERVAL。有没有办法通过触发器OptimizationRun
手动分区CaseId
?为了帮助说明这个问题,每个案例的数据范围从15MiB到1.5GiB,其中任何行都在20k到2M之间。
更新:数据库的当前大小约为1.5TB。
答案 0 :(得分:7)
为数据库删除数据是一项艰巨的工作。它必须在映像之前创建,更新索引,编写重做日志并删除数据。这是一个缓慢的过程。如果您可以有一个窗口来执行此任务,那么最简单,最快捷的方法是构建包含所需数据的新表。删除旧表并重命名新表。 这需要一些设置工作,这是显而易见的,但很有可能。 不那么激烈的一步是在删除发生之前删除索引。我的投票将用于CTAS(Create Table As Select from)并构建新表。 一个好的分区模式肯定会有所帮助,也许在下一个版本中,Oracle可以组合间隔和引用分区。拥有它会非常好。
无法对删除执行禁用日志记录....但CTAS可以使用nologging。准备好后进行备份,并确保将数据文件传输到备用数据库(如果有)。
答案 1 :(得分:2)
只是一些想法:
我假设你有所有外键的索引。 ON DELETE CASCADE将保持行级别锁定,直到案例删除完成,并且没有索引将保持表锁定我相信并且当然超级慢
您是否有任何延迟约束?这很可能会减慢Oracle级联各种表删除的速度
您是否尝试为所有受影响的表单独执行删除操作(而不是依赖于删除级联)?不那么容易,但你可能会感到惊讶。
编辑:
还有一个想法。您可以考虑在Case表上执行SOFT删除,这意味着您有一个状态字段,可以告诉您的应用程序是否应该考虑该案例。此标志可能有许多不同的值,但可能“A”表示活动,“I”表示非活动状态。假设你总是使用Case作为连接到其他表的驱动/主表,你可以避免HARD一起删除(如果你愿意,偶尔可以在任何时间表上清理几小时)。当然,应用程序需要知道这个标志,并且你将加入到Case表中。可能适合您的情况,也可能不适合......
答案 2 :(得分:1)
CASCADE DELETE
在内部逐慢慢慢地运行,呃,逐行。
一些选项:
让您的清除作业快照所有要清除到CTAS临时表中的案例。然后让您的清除作业循环遍历该表,分别删除每个案例(及其子项)。这可能会令人不愉快,特别是如果遇到数百万个后代行。我们不得不在[业务编辑]最近更改其中一个流程,以确定哪些最终父母有子计数会有问题,然后使用rownum
限制器删除有问题的子表(s )。这并不快,但至少从撤销/重做管理的角度来看,通过设置任何交易的大小上限来更安全。
如果您使用CASCADE DELETE
作为一种便利,您可能永远不会这样做。您必须编写一个更复杂的清除例程,从您的依赖树中“自下而上”删除。
如果您能够在软删除上进行撤消/重做生成,则可以对DeleteFlag
上的最终父级进行范围分区,然后使用ENABLE ROW对所有表进行分区BY REFERENCE
运动。在软删除时移动行会产生撤消/重做成本,但是当最终清除时,它会截断DeleteFlag = 1
的分区,仅此而已。
添加存储空间相对便宜。如果有基于日期的保留选项,请使用它,只需让软删除选项隐藏应用程序前端的数据。它不够优雅,但是,CASCADE DELETE
也是如此。
答案 3 :(得分:0)
使用Enterprise Manager创建AWR报告并通过statspack analyzer运行它,它将为您提供有关系统瓶颈的详细说明。 AWR报告是一个文本文件,其中包含有关数据库在特定时间内完成的内容以及花费的时间的所有类型的数据....该statspack分析器是一种自动DBA,告诉您该怎么做。
忘记分区,直到Statspack Analyzer告诉您它们可能有用,并且您有一些可用于分发I / O的空闲磁盘。
不要考虑截断。它强制提交......
BTW,我不隶属于Statspack Analyzer,但我认为这对Oracle来说是一种非常可行的一般调整方法,特别是如果没有DBA。答案 4 :(得分:0)
不建议使用实时数据库。