我们如何调整此删除查询?

时间:2012-05-15 14:50:18

标签: sql oracle plsql

Justin,根据你的建议,我在这里添加了循环..

无论如何我们可以调整这个程序吗?我还没有测试过。

这里我们只是在90天历史记录之前删除主表和子表中的记录。 假设表中有超过20k的记录可供删除。在这里我为每个5k记录提交了..请知道我在这里是不是错了吗?

create or replace 
Procedure PURGE_CLE_ALL_STATUS 
 ( days_in IN number ) 
  IS 
  LV_EXCEPTIONID NUMBER;    
i number := 0;  


cursor s1 is 
        select EXCEPTIONID 
          from EXCEPTIONREC --- master table 
          where TIME_STAMP < (sysdate -days_in); 

BEGIN  

for c1 in s1 loop

     delete from EXCEPTIONRECALTKEY   -- child table 
     where EXCEPTIONID =c1.EXCEPTIONID ; 

     delete from EXCEPTIONREC 
     where EXCEPTIONID =c1.EXCEPTIONID; 

     i := i + 1;              

     if i > 5000 then      
      commit;         
      i := 0;      
     end if;  

end loop;  


commit;      

close S1; 
EXCEPTION 
WHEN OTHERS THEN 
      raise_application_error(-20001,'An error was encountered - '|| 
                                      SQLCODE||' -ERROR- '||SQLERRM); 
END; 
/

2 个答案:

答案 0 :(得分:3)

而不是游标..你可以直接在delete语句中给出条件..

如下所示 -

create or replace
Procedure PURGE_CLE_ALL_STATUS
 ( days_in IN number )
  IS
  LV_EXCEPTIONID NUMBER;   

BEGIN    

     delete from EXCEPTIONRECALTKEY   -- child table
     where EXCEPTIONID = -- (1)
          (select EXCEPTIONID
          from EXCEPTIONREC --- master table
          where TIME_STAMP < (sysdate -days_in));

     delete from EXCEPTIONREC
     where EXCEPTIONID = --(2)
          (select EXCEPTIONID
          from EXCEPTIONREC --- master table
          where TIME_STAMP < (sysdate -days_in));

commit;     
end if;
close c1;
END;
/

我完全赞同Justin Cave ..他给了我很好的观点.. 如果您从光标中获取多行...您可以在(1)和(2)处使用in代替=

答案 1 :(得分:0)

  
    
      

“在90天历史记录之前从主表和子表中删除记录”

    
  

要获得完整的性能优势,您应该实现分区表。更改设计中的这一变化,但可能不会改变您的申请。

您的用例是定期删除数据。您尝试创建每日或每周分区,将新数据存储在较新的分区和分区中。定期删除旧分区。

由于您尝试删除超过90天的数据,因此当前的删除方式会有性能瓶颈。让我们说每天有10,000条记录,那么到第90天就有90 * 10000条。定位&amp;从9000万条记录中删除少量记录将始终是缓慢的&amp;创造一些其他锁定问题。