删除逻辑需要很长时间才能在 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 天删除一个分区。
我正在尝试对删除过程使用以下语句,它必须删除大约 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 天删除一个分区。