如何调整不在查询中

时间:2019-03-11 06:17:22

标签: sql oracle oracle10g query-optimization

请调整我的查询。执行过程花费了17秒

  SELECT grirno, grirdate
    FROM grirmain
   WHERE     grirno NOT IN
                 (SELECT grirno
                    FROM grir_pass
                   WHERE ins_check IS NOT NULL AND grirdate > '01-apr-2013')
         AND grirno IS NOT NULL
         AND chkuser IS NOT NULL
         AND grirdate > '01-apr-2013'
ORDER BY TO_NUMBER (SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,(  INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC

2 个答案:

答案 0 :(得分:1)

我建议使用NOT EXISTS编写此代码:

    SELECT m.grirno, m.grirdate
    FROM grirmain m
    WHERE NOT EXISTS (SELECT 1
                      FROM grir_pass p
                      WHERE g.grirno = p.grirno AND
                            p.ins_check IS NOT NULL AND
                            p.grirdate > DATE '2018-04-01'
                      ) AND
          m.grirno IS NOT NULL AND
          m.chkuser IS NOT NULL AND
          m.grirdate > DATE '2018-04-01'
ORDER BY TO_NUMBER(SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,(  INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC;

然后,您想要在grir_pass(grirno, grirdate, ins_check)grirmain(grirno, grirdate, chkuser)上建立索引。

答案 1 :(得分:0)

您的子查询实际上似乎与外部查询完全 non 不相关。这样,Oracle最有可能执行一次,并缓存结果以供以后使用。我可以建议以下索引:

CREATE INDEX idx ON grirmain (gridate, girano, chksuer);

此索引至少应让Oracle快速处理WHERE子句,此外,它涵盖SELECT子句中的两列。如前所述,不相关的子查询应该执行一次然后缓存。

对于ORDER BY子句,索引可能对此无济于事,Oracle必须手动进行排序。