首页 > 解决方案 > Oracle 过程优化

问题描述

我在 Oracle 中有一个表,每天都会填充大约。35 万条记录。我创建了一个程序来在表中只保留 2 个日期,当插入了第三个不同日期的记录时,它将删除具有最小日期的记录。

下面的解决方案有效,但执行时间太长,因为表中有 1M 条记录:

CREATE OR REPLACE PROCEDURE DELETE_PREV_DT
 
 AS

nCount NUMBER;
tablename  varchar2(50);

BEGIN
  FOR aRow IN (SELECT *
                 FROM TTTAAAA
                 )
  LOOP
  tablename := 'TTTAAAA';
  
  
    EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT DATE_ACCUMULATED) FROM ' || tablename
      INTO nCount;

    IF nCount > 2 THEN
      EXECUTE IMMEDIATE 'DELETE FROM ' || tablename ||
                           ' WHERE DATE_ACCUMULATED = (SELECT MIN(DATE_ACCUMULATED) ' ||
                                                 'FROM ' || tablename || ')';
    END IF;
  END LOOP;
END;
/

有人可以提供修改,以便此过程可以更快地运行吗?

标签: sqloracleplsqlsql-delete

解决方案


由于动态 SQL,逐行承诺是缓慢的,以及上下文切换。

这种方法怎么样?对日期进行排序,删除不在前 2 位的日期。

SQL> select * from test order by datum, id;

        ID DATUM
---------- ----------
         1 21.08.2020
         2 21.08.2020
         3 21.08.2020
         4 22.08.2020
         5 22.08.2020
         6 23.08.2020
         7 23.08.2020
         8 24.08.2020

8 rows selected.

SQL> delete from test t
  2  where t.datum in (select x.datum
  3                    from (select a.datum,
  4                                 dense_rank() over (order by a.datum desc) rn
  5                          from test a
  6                         ) x
  7                    where x.rn > 2
  8                   );

5 rows deleted.

SQL> select * from test order by datum, id;

        ID DATUM
---------- ----------
         6 23.08.2020
         7 23.08.2020
         8 24.08.2020

SQL>

推荐阅读