2017-06-25 5 views
0

私たちの生産データベースにテーブルがあります。 それはサイズarround 220ギガビット ここで指定された次のクエリを実行しているとき ダミーのシナリオで多くの時間がかかります。 以下のクエリの時間を短縮できますか?実行時間が非常に長く、それを減らす方法

ヘルプは高く評価されます。

DELETE FROM testcpy1_bkp 
WHERE (num, dt, cd) IN ( SELECT num, dt, 899 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) != 899 OR MIN (cd) != 899) 
OR ( (num, dt, cd) IN 
( SELECT num, dt, MAX (cd) 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) = 899 AND MIN (cd) = 899) 
AND ROWID NOT IN ( SELECT MIN (ROWID) 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) = 899 AND MIN (cd) = 899)); 


DELETE FROM testcpy1_bkp t1 
WHERE ROWID NOT IN 
(SELECT MAX (ROWID) 
FROM testcpy1_bkp t2 
WHERE t1.num = t2.num AND t1.dt = T2.DT AND t1.cd = t2.cd); 
+0

*ディスク上のテーブルのサイズ*は有用なメトリックではありません。一方、*行数は*です。また、フィルタリング条件を満たす行の数。どのようなインデックスがありますか?実行計画とは何ですか?クエリチューニングはすべて詳細についてです。他のいくつかの[クエリ最適化についての質問](https://stackoverflow.com/questions/tagged/oracle+query-optimization)を読んだら、あなたの質問がなぜ現在の形で答えることができないのかを理解し始めるべきです。 – APC

+0

この問題を解決できましたか? – dybzon

答えて

0

あなたのクエリは、削除している同じテーブルに対していくつかの検索を実行しています。あなたの情報に基づいて、私はこれが非常に大きなテーブルであると仮定します。これはルックアップを高価にします。

DELETEステートメントのWHERE句からサブクエリを選択し、これらの値をテンポラリテーブルに選択してから、テンポラリテーブルの値に基づいてDELETEステートメントを実行します。これにより、クエリのパフォーマンスが大幅に向上します。

それはこのようになります:

INSERT INTO #TempTestCPY1 
SELECT num, dt, 899 AS cd 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) != 899 OR MIN (cd) != 899 

INSERT INTO #TempTestCPY2 
SELECT num, dt, MAX (cd) AS cd 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) = 899 AND MIN (cd) = 899 

INSERT INTO #TempTestCPY3 
SELECT MIN (ROWID) AS ROWID 
FROM testcpy1_bkp 
GROUP BY num, dt 
HAVING MAX (cd) = 899 AND MIN (cd) = 899 

DELETE FROM testcpy1_bkp 
WHERE 
    (num, dt, cd) IN 
     (SELECT num, dt, cd FROM #TempTestCPY1) 
    OR ((num, dt, cd) IN 
     (SELECT num, dt, cd FROM #TempTestCPY2) 
     AND ROWID NOT IN 
     (SELECT ROWID FROM #TempTestCPY3)); 

INSERT INTO #TempTestCPY4 
SELECT MAX (ROWID) ROWID 
FROM testcpy1_bkp 
GROUP BY num, dt, cd 

DELETE FROM testcpy1_bkp t1 
WHERE ROWID NOT IN 
(SELECT ROWID FROM #TempTestCPY4 WHERE t1.num = t2.num AND t1.dt = T2.DT AND t1.cd = t2.cd); 

あなたはそれはあなたがあなたのDELETEを実行する前にDROPを完済し、その後REBUILDであろうと、あなたのテーブルの上にすべてのインデックスを持っているかどうか私も検討します。たとえば、クラスタ化された列ストア索引からのDELETINGは非常に高価な操作になります。ヒープ・テーブルからの削除はコストがかかりません。したがって、クラスタ化された列ストア・インデックスの削除および再構築はしばしば効果的です。

あなたが提供した情報に基づいて考えることができます。それが役に立てば幸い!