优化查询 - 条件作为复杂查询的结果

时间:2017-08-22 09:44:23

标签: oracle optimization

我有一个如下代码。 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')
                 ))

3 个答案:

答案 0 :(得分: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对)。

答案 1 :(得分:0)

你能看到它有效并且能给你带来更好的表现吗?我试图在WHERE条件下使用middle_office.f_d_obchody_zmeny_test只做一个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')
             )
        )

答案 2 :(得分: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')))