删除操作间歇性减慢 oracle 11g

Delete Operation Slows down intermittently oracle 11g

我们在生产环境中进行了审计 Table,我们每天在 PL/SQL 批次中删除近 1500 万条数据(超过几天的数据)。如果情况良好,此查询需要 1.5 小时才能删除相同的数据。但是有时候,即使在 4 小时内,这也不会间歇性地删除相同数量的数据。此 table 上没有触发器,已为创建的列编制索引。

DELETE FROM SIEBEL.CX_AUDIT_SEARCH
WHERE CREATED < '20-MAy-2020' AND rownum <= 10000;

解释 pla:

DELETE STATEMENT    ALL_ROWS    6   10000   180000                  
DELETE SIEBEL.CX_AUDIT_SEARCH                                   
COUNT(STOPKEY)                                  ROWNUM<=10000
INDEX(RANGE SCAN) SIEBEL.CX_AUDIT_SEARCH_U1 ANALYZED    6   170692  3072456             "CREATED"<'20-MAy-2020' 

能否请您提出任何可能的原因。

评论有点长

对于此过程,您想要分区 table。这会将每个分区的 table 存储在单独的 "files" 中。并且可以删除分区——这个过程比删除行要快得多。

您已将要删除的行描述为早于特定日期的行。这是分区解决方案的最佳点。

您可以在 documentation 中了解更多信息。我很惊讶您可以拥有如此大的数据库而不知道此功能。

很明显这是一个很忙的table。 15M rows/day 表示大约 10416 rows/minute,这意味着在您删除这些行时,正在插入数千条记录。当 Oracle 尝试删除旧行并更新 CREATED 索引时,将插入并提交更多行。

我看到您正在尝试一次删除 10000 行。我假设你在这 10000 行之后提交,所以下面的方法可能会更快一些,因为 SELECT 只是 运行 一次而且你不会重新扫描 1500 次繁忙的 table.. .

declare 
cursor c_rowids is
  SELECT T.ROWID
      FROM SIEBEL.CX_AUDIT_SEARCH T
     WHERE CREATED < '20-MAy-2020';
type t_tbl_rowids is table of rowid;
tbl_rowids t_tbl_rowids;
begin
  open c_rowids;
  Loop
    fetch c_rowids bulk collect into tbl_rowids limit 10000;
    exit when tbl_rowids.count = 0;
    forall i in 1..tbl_rowids.count
      DELETE FROM SIEBEL.CX_AUDIT_SEARCH
        WHERE ROWID = tbl_rowids(i);

    COMMIT;
  End loop;
  close c_rowids;
end;