如何调整删除查询?

时间:2016-03-21 05:33:17

标签: sql oracle sql-delete

我正在尝试从表中删除一个数据,该表的主键由多个具有大数据的表引用。我在下面尝试了一个查询需要花费大量时间来执行然后我想放弃约束并重建它们,但是有没有替代方法,比如在匿名块中编写一些代码来执行更好的!!请让我知道你的建议。

DELETE FROM <table_name1> a
    WHERE 
    a.status='I'
    AND NOT EXISTS  
            (SELECT b.id
            FROM <table_name2> b
            WHERE a.id=b.id)
    AND NOT EXISTS  
            (SELECT c.id 
            FROM <table_name3> c
            WHERE a.id=c.id);       
    COMMIT;

谢谢,

与Pradeep

3 个答案:

答案 0 :(得分:0)

确保索引所有外键列。这可以产生巨大的差异。以下是指向博客条目的链接,该博客条目描述了查找非索引外键列的方法。

http://blog.go-faster.co.uk/2007/10/tm-locking-checking-for-missing-indexes.html

答案 1 :(得分:0)

我认为CBO将使用 TABLE ACCESS FULL 到table_name1和 INDEX FAST FULL SCAN 到table_name2和table_name3进行散列连接。也许最好只使用 INDEX FAST FULL SCAN 预先删除所有ID,然后使用INDEX ACCESS删除所选行:

declare
  v_list is table of number;
begin
  select t1.id 
     bulk collect into v_list 
  from <<table_name1>> t1
  left join <<table_name2>> t2 on (t1.id = t2.id)
  left join <<table_name3>> t3 on (t1.id = t3.id)
  where nvl(t2.id,t3.id) is null;

  forall i in v_list.first..v_list.last
  delete from <<table_name1>> t
  where t.id = v_list(i)
    and t.status = 'I';

  commit;  
end;

请尝试这个/但我不确定它会对你有所帮助。感谢。

答案 2 :(得分:0)

我会尝试使子查询独立于周围的语句。因此,子查询始终相同,只需要计算一次,并且可以更好地优化语句。

DELETE FROM <table_name1> a
    WHERE 
    a.status='I'
    AND a.id NOT IN
            (SELECT b.id
            FROM <table_name2> b)
    AND a.id NOT IN
            (SELECT c.id 
            FROM <table_name3> c);