有没有更好的方法来优化这个清除查询?

问题描述 投票:0回答:1

我必须创建一个oracle程序来删除订阅状态被取消且数据超过2个月的客户的所有数据。 总共有 5 亿条记录,大约有 1 亿条需要删除。

我必须创建一个脚本,以便它在每次运行中删除 500 万个,因为一起完成整个操作将花费太长时间。 这就是我所创造的。有没有办法进一步优化?

DECLARE
    rows_deleted   NUMBER := 0;
    max_rows_to_delete NUMBER := 5000000;
    retention_date DATE := trunc(sysdate) - INTERVAL '2' MONTH;
BEGIN
    DELETE FROM subs
    WHERE
        EXISTS (
            SELECT
                1
            FROM
                Sub_status ss
            WHERE
                    sub.id = ss.id
                AND ss.status= 'cancel'
        )
        AND sub.date <= retention_date
        AND ROWNUM <= max_rows_to_delete;

    rows_deleted := SQL%rowcount;

    -- Log number of rows deleted
    dbms_output.put_line('Deleted ' || rows_deleted || ' rows');

    COMMIT; -- Commit changes after successful completion
EXCEPTION
    WHEN OTHERS THEN
        -- Handle exceptions or errors if necessary
        ROLLBACK; -- Rollback the transaction if an error occurs
        dbms_output.put_line('Error: ' || sqlerrm);
END;

sql oracle procedure
1个回答
0
投票

创建一个函数,该函数接受

id
并查找
sub_status
并返回
status
:

CREATE OR REPLACE getsubstatus(in_id integer)
  RETURN varchar2 DETERMINISTIC PARALLEL_ENABLE
AS
  PRAGMA UDF;
  var_status;
BEGIN
  SELECT status
    INTO var_status
    FROM sub_status
   WHERE id = in_id;

  RETURN var_status;
END;

然后通过查询

all_tab_partitions
获取这些足够旧的分区的分区名称,以便进行归档,并且对于每个分区,使用以下语法移动(重组)分区:

ALTER TABLE subs MOVE PARTITION p202301 INCLUDING ROWS WHERE getsubstatus(id) != 'cancel' PARALLEL(16)
.

Oracle 将在内部创建一个新的分区段,仅由状态不是

cancel
的行组成。如果要删除的目标行是段的重要部分,则插入幸存者比删除快得多。 20%(500m 中的 100m)非常重要。

© www.soinside.com 2019 - 2024. All rights reserved.