2017-08-22 16 views
0

私は以下のようなコードを持っています。 where節の条件は、多数の条件を持つ非常に複雑な照会の結果であり、処理に時間がかかりすぎる最小値と最大値を検索します。それを最適化する方法はありますか?前もって感謝します。複合クエリの結果としてのクエリ条件の最適化

SELECT * 
    FROM middle_office.f_d_obchody_zmeny_test a 
    WHERE dwh_insert_process = 
     (SELECT MAX(dwh_insert_process) dwh_insert_process 
      FROM middle_office.f_d_obchody_zmeny_test b 
      WHERE b.id_obchodu = a.id_obchodu 
      AND b.id_obchodu_poradi = a.id_obchodu_poradi 
      ) 
    AND (datum_obchodu >= to_date('01.08.2017', 'dd.mm.yyyy') OR 
     ((datum_obchodu < to_date('01.08.2017', 'dd.mm.yyyy')) AND 
     ((SELECT MIN(c.insert_sysdate) insert_sysdate 
       FROM middle_office.f_d_obchody_zmeny_test c 
       WHERE c.id_obchodu = a.id_obchodu 
       AND c.id_obchodu_poradi = a.id_obchodu_poradi)) >=to_date('01.08.2017', 'dd.mm.yyyy') 
       )) 

答えて

1

私はこれがそうのような分析関数を書き換えることができると思います:

SELECT * 
FROM (SELECT a.*, 
       MAX(dwh_insert_process) OVER (PARTITION BY id_obchodu, id_obchodu_poradi) max_dwh_insert_process, 
       MIN(insert_sysdate) OVER (PARTITION BY id_obchodu, id_obchodu_poradi) min_insert_sysdate 
     FROM middle_offic.f_d_obchody_zmeny_test a) 
WHERE dwh_insert_process = max_dwh_insert_process 
AND (datatum_obchodu >= to_date('01.08.2017', 'dd.mm.yyyy') 
     OR 
     (datatum_obchodu < to_date('01.08.2017', 'dd.mm.yyyy') 
     AND min_insert_sysdate >= to_date('01.08.2017', 'dd.mm.yyyy'))); 

あなたはこのクエリは、あなたの現在のクエリと同じ結果を返すことを確認するためにテストする必要があるだろうが、それがあるべき一度テーブルを照会するだけで、少しパフォーマンスが向上します。さらに、各キー(各id_obchoduとid_obchodu_poradiペアごとに)ではなく、min/maxが1回で済むようになりました。

+0

に参加し、私の質問にすべてのソリューションは、あなたに感謝、 – JanFi86

0

これが動作し、より良いパフォーマンスを得ることができますか?私はWHERE条件でmiddle_office.f_d_obchody_zmeny_testを使用して1つのSELECTだけを実行しようとしましたが、実行についてはわかりません。

SELECT a.* 
FROM middle_office.f_d_obchody_zmeny_test a 
LEFT JOIN (SELECT id_obchodu,id_obchodu_poradi,MAX(dwh_insert_process) dwh_insert_process, MIN(c.insert_sysdate) insert_sysdate 
      FROM middle_office.f_d_obchody_zmeny_test 
      GROUP BY id_obchodu,id_obchodu_poradi) D ON D.id_obchodu = a.id_obchodu AND D.id_obchodu_poradi = a.id_obchodu_poradi 
WHERE a.dwh_insert_process = D.dwh_insert_process 
    AND (a.datum_obchodu >= to_date('01.08.2017', 'dd.mm.yyyy') 
     OR ((datum_obchodu < to_date('01.08.2017', 'dd.mm.yyyy')) 
      AND D.insert_sysdate >=to_date('01.08.2017', 'dd.mm.yyyy') 
      ) 
     ) 
+0

はありがとうありがとう、私の質問にすべてのソリューションは、効率的であり、効率的であり、あなたに感謝 – JanFi86

0

はを利用するために、このようなものかもしれませ

SELECT * 
FROM middle_office.f_d_obchody_zmeny_test a 
INNER JOIN (SELECT id_obchodu,id_obchodu_poradi, MAX(dwh_insert_process) dwh_insert_process, MIN(c.insert_sysdate) insert_sysdate 
      FROM middle_office.f_d_obchody_zmeny_test b 
      GROUP BY id_obchodu,id_obchodu_poradi) b 
      ON b.id_obchodu = a.id_obchodu 
      AND b.id_obchodu_poradi = a.id_obchodu_poradi 
      AND a.dwh_insert_process = b.dwh_insert_process 
WHERE (datum_obchodu >= to_date('01.08.2017', 'dd.mm.yyyy') OR 
    (datum_obchodu < to_date('01.08.2017', 'dd.mm.yyyy') AND b.insert_sysdate >=to_date('01.08.2017', 'dd.mm.yyyy'))) 
+0

ありがとう、私の質問に対するすべてのソリューションは効率的です、ありがとう – JanFi86

関連する問題