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