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

Delete logic is taking a very long time to process in Oracle

我正在尝试对删除过程使用以下语句,它必须删除大约 23566424 行,但是 oracle 需要将近 3 个小时才能完成该过程,我们已经在“SCHEDULE_DATE_KEY 上创建了一个索引“但是,这个过程仍然非常 slow.Can 有人建议如何在 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'
  );

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

一种更快的方法可能是创建一个新的 table 要保留的行,例如:

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'
  );

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

最后删除旧的 table 并重命名新的。

您可以尝试测试过滤后的 table 移动。这有一个在线条款。因此,您可以在应用程序仍处于 运行.

时执行此操作

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

搬个Table 创建并填充新测试 table.

DROP TABLE t1 PURGE;

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

检查 table 的内容。

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>

移动table,过滤掉ID值大于50的行

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

检查 table 的内容。

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 之间的行已被删除。

如上所述,如果可能最好对 table abs 进行分区,作为日常任务的一部分,每 N 天删除一个分区。