2016-09-16 100 views
2

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

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 
+0

请发表您的表结构,包括索引,以及解释查询的计划,以帮助人们了解发生了什么,以及如何查询可以提高 – Aleksej

+1

记录是否不同?如果是,请使用UNION ALL。没有更多的技巧,除非发布执行计划:) –

+0

其相当长,我可以将它作为文件附件张贴在这里吗?不,记录不明显 – QuickDrawMcgraw

回答

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

谢谢骨科医生,使执行时间缩短了60%。我非常感谢你的帮助! – QuickDrawMcgraw

+0

并感谢您转换为使用显式连接。没有人应该使用隐式联接。 – HLGEM

0

考虑一个SELECT写整个查询(使用包围曝光,ANDs,ORs),这将删除UNION的所有低效重复检查。

您可以尝试使用UNION ALL,因为Pawel-Dyl建议,但是如果您可以完成这项工作,则可以将它全部写入一个SELECT中,这会为优化程序提供更多选项。

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 
+0

如果引用中存在多个行,则每个int_tran_id/ach_id可能会引入额外的行,app_data或ach表。除非你确定所有连接都是1-1条件,否则你需要额外的清除重复项。 – Boneist