我需要一些帮助来优化

时间:2016-05-10 09:25:17

标签: sql oracle oracle11g

我想优化此查询,但仅使用索引,提示,群集和pctfree以及pctused。感谢。

WITH
     A AS (SELECT SSN from contracts where (end_date is null or end_date>sysdate)),
     B AS (SELECT SSN,start_date, NVL(end_date,sysdate) finish,
         (NVL(end_date,sysdate)-start_date) length
     FROM CONTRACTS NATURAL JOIN A)
     SELECT SSN
        FROM B
        GROUP BY SSN HAVING (Max(finish)-MIN(start_date)) > SUM(length)

2 个答案:

答案 0 :(得分:0)

您应该能够通过使用分析查询来摆脱连接:

SELECT SSN
FROM   (
  SELECT SSN,
         start_date,
         NVL( end_date, SYSDATE ) finish,
         COUNT( CASE WHEN end_date IS NULL OR end_date > SYSDATE THEN 1 END )
           OVER ( PARTITION BY SSN ) AS has_invalid_end_date,
  FROM   contracts
)
WHERE  has_invalid_end_date > 0
GROUP BY SSN
HAVING   MAX( finish ) - MIN( start_date ) > SUM( finish - start_date );

答案 1 :(得分:0)

我认为你可以把它重写为:

with b as (select ssn,
                  start_date,
                  nvl(end_date, sysdate) finish_date,
                  nvl(end_date, sysdate) - start_date duration
           from   contracts)
select   ssn
from     b
where    end_date is null
or       end_date > sysdate
group by ssn
having   max(finish_date) - min(start_date) > sum(duration);

您可能还会受益于(ssn,start_date,end_date)上的索引。