使用sql的UNION子句性能问题

时间:2016-09-16 12:33:25

标签: sql oracle union

我有下面的union子句导致整个存储过程运行得非常慢。我使用union来从同一个表中收集信息,但是第二个和第三个union子句也加入到其他表中以进行过滤。我知道这可能不是最好的编码方法,并希望有人可以指导我更好的语法。

select ss.int_tran_id 
from status ss 
where ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF')
UNION
select ss.int_tran_id 
from status ss, references rf
where ss.int_tran_id = rf.int_tran_id
and ss.stage = 'PREVDAY'
and rf.mid_ref IS NOT NULL
UNION
select ss.int_tran_id 
from status ss, app_data ad, ach aa
where ss.int_tran_id = ad.int_tran_id
and ad.app_data_id = aa.ach_id
and ss.stage = 'PREVDAY'
and aa.par_number IS NOT NULL

3 个答案:

答案 0 :(得分:2)

我认为您可以将其重写为状态表上的单个查询,使用OR来测试每个方案,如下所示:

SELECT ss.int_tran_id
FROM   status SS
WHERE  ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF')
OR     (ss.stage = 'PREVDAY'
        AND (EXISTS (SELECT NULL
                     FROM   references rf
                     WHERE  ss.int_tran_id = rf.int_tran_id
                     AND    rf.mid_ref IS NOT NULL)
             OR EXISTS (SELECT NULL
                        FROM   app_data ad
                               INNER JOIN ach aa
                                 ON (ad.app_data_id = aa.ach_id)
                        WHERE  ss.int_tran_id = ad.int_tran_id
                        AND    aa.par_number IS NOT NULL)));

答案 1 :(得分:0)

考虑在一个SELECT中编写整个查询(使用包围,AND,OR),这将删除UNION的所有低效复制检查。

你可以尝试使用Pawel-Dyl建议的UNION ALL,但是如果你可以做到这一点,你可以在一个SELECT中编写它,这为优化器提供了更多的选择。

答案 2 :(得分:0)

我的变体:

select ss.int_tran_id 
from status ss
left join references rf on (ss.stage = 'PREVDAY'
                            and ss.int_tran_id = rf.int_tran_id
                            and rf.mid_ref IS NOT NULL)
left join app_data ad on (ss.stage = 'PREVDAY'
                          and ss.int_tran_id = ad.int_tran_id)
left join ach aa on (ss.stage = 'PREVDAY'
                     and ad.app_data_id = aa.ach_id
                     and aa.par_number IS NOT NULL)
where ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF')
   or rf.int_tran_id is not null
   or aa.ach_id is not null