delete操作会间歇性地减慢oracle11g的速度

vxf3dgd4  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(598)

我们在生产环境中有一个审计表,我们每天在pl/sql批处理中删除将近1500万个数据(比几天旧的数据)。如果天气好,此查询需要1.5小时才能删除相同的数据。但有时,即使在4小时内,也会断断续续地删除相同数量的数据。此表上没有触发器,创建的列被编入索引。

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'

你能告诉我可能的原因吗。

kninwzqo

kninwzqo1#

很明显这张table很忙。15m行/天意味着大约10416行/分钟,这意味着在删除这些行时,将插入数千条记录。当oracle试图删除旧的行并更新创建的索引时,会插入和提交更多的行。
我看到你试图一次删除10000行。我假设您在这10000行之后提交,所以下面的方法可能会快一点,因为select只运行一次,并且您不会重新扫描繁忙表的1500倍。。。

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;
bbuxkriu

bbuxkriu2#

这是一个有点长的评论。
对于这个过程,您需要对表进行分区。这将表存储在每个分区的单独“文件”中。并且可以删除分区——这个过程比删除行快得多。
您已将要删除的行描述为早于特定日期的行。这是分区解决方案的最佳选择。
您可以在文档中了解更多信息。我很惊讶你有这么大的数据库却不知道这个功能。

相关问题