2016-11-11 1 views
1

나는 행 1345222의 집합에 대해 긴 실행 시간 aprox 20 분이 걸리는 아래 쿼리를 가지고 있습니다.이 튜닝 방법은 특별히 절 사이의 비교입니까?시간이 오래 걸립니다. 튜닝 SQL 쿼리

<code> 
SELECT /*+ PARALLEL(32) */ upexp.item, 
        upexp.loc, 
        startdate, 
        sku_exp.bucket_size, 
        MAX(upexp.sku_multiplier) OVER (PARTITION BY upexp.item,upexp.loc) max_sm 
         FROM 
           (SELECT bucket bkt, 
             MIN(dates) OVER (PARTITION BY bucket) minbk, 
             MAX(dates) OVER (PARTITION BY bucket) maxbk 
           FROM (
             SELECT LEVEL AS sl, 
             NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * LEVEL - 8,'SATURDAY') AS dates, 
             CEIL (LEVEL/4) AS bucket 
             FROM DUAL 
             CONNECT BY LEVEL <= ((4 - MOD (78, 4) + 78) + 78)) yy 
           -- GROUP BY bucket 
           ) minmaxdate , 
         stsc.u_promo_sku_expand sku_exp, 
         stsc.u_promo_upload_expand upexp 
         WHERE sku_exp.bucket_size = 4 
         AND sku_exp.startdate BETWEEN minmaxdate.minbk AND minmaxdate.maxbk 
         AND upexp.item = sku_exp.item 
         AND upexp.loc = sku_exp.loc 
         AND upexp.u_country = sku_exp.u_country 
         AND ((eff BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6) 
         OR (disc BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6) 
         OR (eff <= minmaxdate.minbk AND disc >= minmaxdate.maxbk+6)) 

</code> 
+1

경우 계획은 다음과 같습니다

이 하나를 시도? 마지막 프리디 케이트 섹션에있는 (eff BETWEEN minmaxdate.minbk 및 minmaxdate.maxbk + 6) 또는 eff <= minmaxdate.minbk AND 디스크> = minmaxdate.maxbk + 6) '는 어떤 경우에도 true입니다. –

+0

실제 테이블? 또한 전체 쿼리에서'SELECT ... FROM DUAL'을 사용하는 이유를 잘 모르겠습니다. 그걸 옮길 수 없니? – FDavidov

+0

MIN/MAX OVER 대신 두 그룹으로 시도하십시오. 그리고 쿼리에 의한 연결을 WITH – Thomas

답변

0

이 블록

(SELECT bucket bkt, 
    MIN(dates) OVER (PARTITION BY bucket) minbk, 
    MAX(dates) OVER (PARTITION BY bucket) maxbk 
FROM (
    SELECT LEVEL AS sl, 
     NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * LEVEL - 8,'SATURDAY') AS dates, 
     CEIL (LEVEL/4) AS bucket 
    FROM DUAL 
    CONNECT BY LEVEL <= ((4 - MOD (78, 4) + 78) + 78)) yy 
    -- GROUP BY bucket 
    ) 

경우에만 최소 및 최대 값을 필요로하기 때문에 쓸모가있을 것으로 보인다.

WITH minmaxdate AS 
    (SELECT 
     NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * 1 - 8,'SATURDAY') AS minbk, 
     NEXT_DAY (TRUNC (SYSDATE, 'YEAR') + 7 * ((4 - MOD (78, 4) + 78) + 78) - 8,'SATURDAY') AS maxbk 
    FROM dual) 
SELECT item, loc, startdate, sku_exp.bucket_size, 
    MAX(upexp.sku_multiplier) OVER (PARTITION BY item, loc) max_sm 
FROM stsc.u_promo_sku_expand sku_exp 
    JOIN stsc.u_promo_upload_expand upexp USING (item, loc, u_country) 
    CROSS JOIN minmaxdate 
WHERE sku_exp.bucket_size = 4 
    AND sku_exp.startdate BETWEEN minmaxdate.minbk AND minmaxdate.maxbk 
    AND (
     eff BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6 
     OR (eff <= minmaxdate.minbk AND disc >= minmaxdate.maxbk+6) 
     OR disc BETWEEN minmaxdate.minbk AND minmaxdate.maxbk+6 
    ); 
+0

ORA-25154 : USING 절의 열 부분에 한정자를 사용할 수 없습니다. 그러나 이것은 효과적입니다. 항목, loc, startdate, bucket_size -MAX (sku_multiplier) OVER (PARTITION BY sku_exp.item, sku_exp.loc) max_sm FROM stsc.u_promo_sku_expand sku_exp JOIN stsc.u_promo_upload_expand USING (item, loc, u_country) WHERE sku_exp.bucket_size = 4 –

관련 문제