存在查询不等于运行速度极慢

时间:2015-02-13 20:11:00

标签: oracle

我正在尝试修改其他人编写的查询,这需要很长时间才能运行。问题与<>有关。存在查询的一部分。知道如何改变它以便更快地运行吗?

SELECT m.level4 center, cc.description, m.employeename, m.empno,
       TO_DATE (ct.tsdate, 'dd-mon-yyyy') tsdate, ct.starttime, ct.endtime,
       ct.DURATION,
       NVL (DECODE (ct.paycode, ' ', 'REG', ct.paycode), 'REG') paycode,
       ct.titlecode, ct.costcenter, m.tsgroup
  FROM clairvia_text ct, MASTER m, costcenteroutbound cc
 WHERE ct.recordtype = '1'
   AND ct.empno = m.empno
   AND m.level4 = cc.center
   AND EXISTS (
          SELECT ct1.recordtype,ct1.empno,ct1.tsdate,ct1.processdate
            FROM clairvia_text ct1
           WHERE ct.recordtype = ct1.recordtype
             AND ct.empno = ct1.empno
             AND ct.tsdate = ct1.tsdate
             AND ct.processdate = ct1.processdate
             group by ct1.recordtype,ct1.empno,ct1.tsdate,ct1.processdate
             having count(*) < 2)

2 个答案:

答案 0 :(得分:0)

Oracle可以通过exists语句和子查询来实现。有几件事要尝试:

  1. 将存在更改为&#34; in&#34;
  2. 将存在更改为group by语句,其中&#34;具有count(1)&gt; 1&#34 ;.这甚至可以改成连接。
  3. 我假设索引不是问题。

答案 1 :(得分:0)

您可以在此处使用analytic function count来消除重复的行。

select * from ( 
    SELECT m.level4 center, cc.description, m.employeename, m.empno,
           TO_DATE (ct.tsdate, 'dd-mon-yyyy') tsdate, ct.starttime, ct.endtime,
           ct.DURATION,
           NVL (DECODE (ct.paycode, ' ', 'REG', ct.paycode), 'REG') paycode,
           ct.titlecode, ct.costcenter, m.tsgroup,
           count(1) over (partition by ct.recordtype,ct.empno,ct.tsdate,ct.processdate
             order by null) cnt
      FROM clairvia_text ct, MASTER m, costcenteroutbound cc
     WHERE ct.recordtype = '1'
       AND ct.empno = m.empno
       AND m.level4 = cc.center
  ) where cnt=1

我没有你的结构和数据,所以我用all_tab_cols运行类似的查询,第一次查询在我的笔记本电脑上花了大约500秒,第二次查询~2s。

-- slow test
select count(1)
  from all_tab_cols atc
    where exists (  
      select 1 
        from all_tab_cols atc1
        where atc1.column_name = atc.column_name
        group by column_name
        having count(1) = 1)

-- fast test
select count(1)
  from (
    select column_name, 
        count(1) over (partition by atc.column_name order by null) cnt
      from all_tab_cols atc
    )
  where cnt = 1