带有子查询的Oracle sql导致性能问题

时间:2013-05-10 18:36:56

标签: sql oracle subquery

使用3个子查询编写oracle sql,但是它会导致超时问题。希望获得有关修复的技术帮助。这是我的疑问:

select   DISTINCT E_reg.applicant_id,
             E_REG.L_NAME, 
             E_REG.F_NAME, 
             E_REG.B_DATE,
            E_REG.REG_DATE,
 from     E_REG,TRANSACTION
where   E_REG.ID=TRANSACTION.PAR_ID
  and       TRANSACTION.BEGIN_DATE BETWEEN to_date ('01-APR-2012')AND to_date('30-JUN-               2012')
and  e_reg.applicant_id NOT IN
              (select applicant_id
                   from w_reg
                  where reg_date <'01-JUL-2012' 
                   and exit_date is NULL or exit_date >='01-APR-2012'
or  e_reg.applicant_id NOT IN
              (select applicant_id
                   from t_reg
                  where reg_date <'01-JUL-2012' 
                   and exit_date is NULL or exit_date>='01-APR-2012')
or  e_reg.applicant_id NOT IN
              (select applicant_id
                   from r_reg
                  where reg_date <'01-JUL-2012' 
                     and o_attend IS NOT NULL
                   and term_date is NULL or term_date >='01-APR-2012')

基本上我们有4个程序可以在(e,w,t和r)。这些都是单独的表格,包含基本的参与者信息。您可能同时在所有4个程序中,applicant_id将是每个人的关键。

交易表包含您在3或4个程序中可能收到的任何服务,而不是具有自己的交易表的r程序。

我想要一个e表中的参与者列表,这些参与者在时间范围内有服务,但同时在任何其他程序中都没有任何服务。他们只会通过电子计划提供服务。它似乎今天早上工作,但它开始超时,而不是运行。我认为它必须是子查询。想知道是否有更好的方法来完成这项工作。

1 个答案:

答案 0 :(得分:1)

我很确定问题是where子句中的括号。您有or个条款正在撤消连接。如果您始终使用ANSI连接语法,则会大大降低发生这种情况的可能性。

以下是替代版本:

select   DISTINCT E_reg.applicant_id,
             E_REG.L_NAME, 
             E_REG.F_NAME, 
             E_REG.B_DATE,
            E_REG.REG_DATE,
 from    E_REG join
         TRANSACTION
         on E_REG.ID=TRANSACTION.PAR_ID
  where TRANSACTION.BEGIN_DATE BETWEEN to_date ('01-APR-2012')AND to_date('30-JUN-               2012')
and  (e_reg.applicant_id NOT IN
              (select applicant_id
                   from w_reg
                  where reg_date <'01-JUL-2012' 
                   and exit_date is NULL or exit_date >='01-APR-2012'
or  e_reg.applicant_id NOT IN
              (select applicant_id
                   from t_reg
                  where reg_date <'01-JUL-2012' 
                   and exit_date is NULL or exit_date>='01-APR-2012')
or  e_reg.applicant_id NOT IN
              (select applicant_id
                   from r_reg
                  where reg_date <'01-JUL-2012' 
                     and o_attend IS NOT NULL
                   and term_date is NULL or term_date >='01-APR-2012')
   )