【问题标题】:Performing mass DELETE operation in Oracle 11g在 Oracle 11g 中执行批量 DELETE 操作
【发布时间】:2013-09-27 17:50:47
【问题描述】:

我有一个表MyTable,其中包含多个带日期的 int 列和一个包含日期的列。日期列有一个如下创建的索引

CREATE INDEX some_index_name ON MyTable(my_date_column)

因为通常会在用户指定的日期范围内查询表格的内容。该表没有指向它的外键,也没有除主键之外的任何其他索引,主键是由序列/触发器填充的自动递增索引。

现在,我遇到的问题是该表上的数据经常在给定时间段内被替换,因为它已经过时了。因此,他们更新的方式是删除给定时间段内的所有条目并插入新条目。删除是使用

DELETE FROM MyTable 
WHERE my_date_column >= initialDate 
  AND my_date_column < endDate

但是,由于删除的行数很大(从 500 万到 1200 万行),因此程序在删除过程中几乎会阻塞。

我可以禁用某些东西以加快操作速度吗?或者也许在索引中指定一个选项以使其更快?我读过一些关于重做空间的内容,但我不知道如何在操作期间禁用它。

编辑:该过程每天运行并删除最后 5 天的数据,然后带来这 5 天的数据(可能在外部源中已更改)并重新插入数据。

删除的数据量与表中的全部数据量相比只是很小的一部分(

【问题讨论】:

  • 行的哪一部分实际发生了变化。如果您要删除 5 天的数据,然后重新插入 5 天的数据,您是否可以重写该过程以执行 MERGE 而不是 DELETE + INSERT?删除期间有哪些“块”? SELECT 语句永远不会被 DML 阻止。也许应用程序变慢(呃)是因为DELETE 使您的 I/O 子系统饱和?还是您的应用程序试图锁定您的DELETE 进程正在删除的行?
  • 哦,Brian,我已经有几个月没有从事那个项目了,所以我再也找不到了。我不确定 Oracle 本身的问题是什么,但我们转移到了 PostgreSQL,并且在那里进行相同的操作要快得多。这就是我们“解决”它的方式。

标签: sql oracle oracle11g sql-delete bulk


【解决方案1】:

我只能想到两种方法来加快速度。

  1. 如果您定期执行此操作,则应考虑按月对表进行分区。然后,您只需删除要删除的月份的分区。这基本上和丢一张桌子一样快。如果我没记错的话,分区需要企业许可证
  2. 用您想要保留的数据创建一个新表(使用create table new_table as select ...),删除旧表并重命名临时表。这会快得多,但缺点是您需要在新表上重新创建所有索引和(主、外键)约束。

【讨论】:

  • 这在 Oracle 中是一种可行的方法吗?:删除较小事务中的行(例如每个事务 10k 行),从而为其他操作留出空间(即同时获得锁)停止并且下一个开始)而不等待一个巨大的操作完成并释放锁?
  • ypercube,我会测试一下,看看它是如何工作的。请将该评论作为答案发布,以便我在测试后提供反馈。
  • @ypercube:在 Oracle 中,小批量删除通常较慢,因为频繁提交实际上会增加工作量。请参阅此处进行冗长的讨论:asktom.oracle.com/pls/apex/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 2013-02-14
  • 1970-01-01
  • 2014-06-24
  • 2017-07-09
  • 2013-09-08
相关资源
最近更新 更多