在 Oracle 中处理删除逻辑需要很长时间

Posted

技术标签:

【中文标题】在 Oracle 中处理删除逻辑需要很长时间【英文标题】:Delete logic is taking a very long time to process in Oracle 【发布时间】:2022-01-06 01:18:52 【问题描述】:

我正在尝试将以下语句用于删除过程,它必须删除大约 23566424 行,但 oracle 需要将近 3 个小时才能完成该过程,我们已经在“SCHEDULE_DATE_KEY”上创建了一个索引,但仍然是该过程速度很慢。有人可以建议如何在 oracle 中更快地删除

DELETE
FROM
  EDWSOURCE.SCHEDULE_DAY_F
WHERE
  SCHEDULE_DATE_KEY >
  (
    SELECT
      LAST_PAYROLL_DATE_KEY
    FROM
      EDWSOURCE.LAST_PAYROLL_DATE
    WHERE
      CURRENT_FLAG = 'Y'
  );

【问题讨论】:

表格的总行数是多少?仅当谓词具有高选择性(与总行数相比,它评估为真的行数非常低)时,索引才可能有助于提高性能。 @astentx 表格总行数为310879005行 您可以尝试alter session enable parallel dml,然后执行deleteparallel 提示:delete /*+parallel(SCHEDULE_DAY_F)*/ from ...。对如此大量的行使用全表扫描而不是索引会更好。如果您需要定期运行此操作,您可以使用SCHEDULE_DATE_KEY 上的分区来简化数据管理,并为所需的分区执行truncate partition @astentx 让我试试我用上面的方法更新你,谢谢你的快速回复。 @karthik 你有没有想过或尝试我的解决方案? 【参考方案1】:

我认为这里没有任何索引有帮助,可能 Oracle 会决定最好的方法是全表扫描,从 300M 中删除 20M 行。它以每秒超过 2000 行的速度删除,这还不错。事实上,任何额外的索引都会减慢它的速度,因为它也必须从索引中删除行条目。

一种更快的方法是创建一个包含您要保留的行的新表,例如:

create table  EDWSOURCE.SCHEDULE_DAY_F_KEEP
as 
select * from  EDWSOURCE.SCHEDULE_DAY_F
where SCHEDULE_DATE_KEY <=
  (
    SELECT
      LAST_PAYROLL_DATE_KEY
    FROM
      EDWSOURCE.LAST_PAYROLL_DATE
    WHERE
      CURRENT_FLAG = 'Y'
  );

然后重新创建任何约束和索引以使用新表。

最后删除旧表并重命名新表。

【讨论】:

您对下面使用过滤表移动的解决方案有何看法 @Pugzly 看起来不错。我从来没有做过,所以不能具体评论。 @Pugzly 我将在开发环境中实现它并在此处更新。【参考方案2】:

您可以尝试测试过滤后的表格移动。这有一个在线条款。因此,您可以在应用程序仍在运行时执行此操作。

注释 12.2 和更高版本的索引将保持有效。在早期版本中,您将需要重建索引,因为它们将变得无效。祝你好运

移动表格 创建并填充一个新的测试表。

DROP TABLE t1 PURGE;

CREATE TABLE t1 AS
SELECT level AS id,
       'Description for ' || level AS description
FROM   dual
CONNECT BY level <= 100;
COMMIT;

检查表格的内容。

SELECT COUNT(*) AS total_rows,
       MIN(id) AS min_id,
       MAX(id) AS max_id
FROM   t1;

TOTAL_ROWS     MIN_ID     MAX_ID
---------- ---------- ----------
       100          1        100

SQL>

移动表格,过滤掉 ID 值大于 50 的行。

ALTER TABLE t1 MOVE ONLINE
  INCLUDING ROWS WHERE id <= 50;

检查表格的内容。

SELECT COUNT(*) AS total_rows,
       MIN(id) AS min_id,
       MAX(id) AS max_id
FROM   t1;

TOTAL_ROWS     MIN_ID     MAX_ID
---------- ---------- ----------
        50          1         50

SQL>

ID 值介于 51 和 100 之间的行已被删除。

如上所述,作为日常任务的一部分,表 abs 每隔 N 天删除一次 PARTITION 可能最好。

【讨论】:

@karthik 完成了我的解决方案练习。如果是这样,请接受并投票 @karthik 我的建议有效吗?

以上是关于在 Oracle 中处理删除逻辑需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

想要从选择查询中处理 5000 条记录在 oracle 数据库中需要很长时间

在 oracle 10g 中更新查询需要很长时间

将逻辑回归模型拟合到 MNIST 数据需要很长时间

使用 OracleDataAccess.Fill(datatable) 更新 DataGridView 需要很长时间

BigQuery - 删除重复记录有时需要很长时间

删除大量记录需要很长时间