2016-03-21 25 views
0

大きなデータを持ついくつかのテーブルでプライマリキーが参照されているテーブルからデータを削除しようとしています。私は以下のクエリを実行しようとしましたが、実行するには時間がかかりました。制約を破棄して再構築することを考えましたが、匿名ブロックでいくつかのコードを書く方が良いでしょう。私の提案をお知らせください。削除クエリをチューニングする方法は?

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; 

プラディープ

+0

実行計画を確認する –

答えて

0

は、すべての外部キー列が索引付けされていることを確認し、

、ありがとうございました。これは大きな違いを生み出すことができます。ここには、インデックスされていない外部キー列を見つける方法を説明するブログエントリへのリンクがあります。

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

0

私は、CBOはハッシュがtable_name2とtable_name3にtable_name1とINDEX FAST FULL SCANする FULL TABLEアクセスの参加でしょうと思います。たぶんだけINDEX FAST FULL SCANを使用してすべてのIDをprecalcする方がよいとより後にすることは、インデックスアクセスを使用して、選択した行を削除します:

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; 

はこれを試してみてください/しかし、私はそれはあなたを助けることはよく分かりません。ありがとう。

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); 
関連する問題