2017-11-26 10 views
0

하나의 지불에 둘 이상의 할당이있을 수 있으므로 첫 번째 일치 (rownum = 1 인 경우) 만 고려해야하므로 조인에 하위 쿼리를 추가해야합니다.조인의 하위 쿼리는 where 절의 외부 쿼리에서 테이블을 사용해야합니까?

그러나 외부 쿼리의 pmt를 할당 조인의 하위 쿼리에 추가하는 것이 가장 적합한 지 잘 모르겠습니다.

실적이 좋지 않을 때마다 다르게해야합니까?

 SELECT 
      pmt.payment_uid, 
      alt.allotment_uid, 

     FROM 
      payment pmt 

/* HERE: is the reference to pmt.pay_key and pmt.client_id 
    incorrect in the below subquery? */ 

      INNER JOIN allotment alc ON alt.allotment_uid = (
       SELECT 
        allotment_uid 
       FROM 
        allotment 
       WHERE 
         pay_key = pmt.pay_key 
        AND 
         pay_code = 'xyz' 
        AND 
         deleted = 'N' 
        AND 
         client_id = pmt.client_id 
        AND 
         ROWNUM = 1 
      ) 

     WHERE 

      AND 
       pmt.deleted = 'N' 
      AND 
       pmt.date_paid >= TO_DATE('2017-07-01') 
      AND 
       pmt.date_paid < TO_DATE('2017-10-01') + 1; 
+0

올바른지 여부는 실행했을 때의 결과에 달려 있습니다. –

+0

큰 데이터를 다루고 있으며 쿼리가 매우 느리게 실행됩니다. 이것이 성능 저하에 기여할 수 있는지 궁금합니다. 가능한 경우 피해야하는 항목 인 경우 ... – NoobSter

+0

하위 쿼리의 상관 관계가 느려질 수 있으므로 rownum에 의존하여 첫 번째 "데이터에 일부 고의적 인 명령을 부과하지 않는 한. 예를 들어 할당 테이블에 날짜 또는 시간 소인 열이 있습니까? "만든 날짜"? (그렇다면 해당 열의 이름은 무엇입니까?) –

답변

0

Explain plan 출력을 보지 않고도 조회에서 성능 문제점을 식별하기 어렵습니다. 당신은 쿼리가 메인 쿼리에서 모든 레코드에 대한 할당에 대한 추가 SELECT를 수행하는 것 같습니다.

다음은 상관 하위 쿼리를 사용하지 않는 버전입니다. 분명히 나는 ​​그것을 시험 할 수 없었다. 간단한 조인을 수행 한 다음 할당 중 하나를 제외한 모든 레코드를 필터링합니다. 희망이 도움이됩니다.

WITH v_payment 
AS 
(
    SELECT 
      pmt.payment_uid, 
      alt.allotment_uid, 
      ROW_NUMBER() OVER(PARTITION BY allotment_id) r_num 
     FROM 
      payment pmt JOIN allotment alt 
          ON (pmt.pay_key = alt.pay_key AND 
           pmt.client_id = alt.client_id) 
     WHERE pmt.deleted = 'N' AND 
      pmt.date_paid >= TO_DATE('2017-07-01') AND 
      pmt.date_paid < TO_DATE('2017-10-01') + 1 AND 
      alt.pay_code = 'xyz' AND 
      alt.deleted = 'N' 
) 
SELECT payment_uid, 
     allotment_uid 
    FROM v_payment 
WHERE r_num = 1; 

이것이 어떻게 수행되는지 알아 봅시다.

+0

over 절에 'order by'이 필요하지만 사용할 열이 절대적으로 명확하지 않습니다. –

+0

할당 번호별로 정렬하여 사용했습니다. 왜 이것이 rownum = 1을 사용하는 것보다 빠르다는 것을 설명 할 수 있습니까? – NoobSter

+0

상관 관계가있는 하위 쿼리는 하위 쿼리가 결과 세트의 각 레코드에 대해 한 번만 실행되는 것이 아니라 결과로 실행될 수 있습니다. 이로 인해 성능이 크게 저하 될 수 있습니다. 최근 오라클이 그러한 쿼리를 대부분 재 작성하기에 충분히 영리하다고 말한 것은 사실입니다. 당신의 원래 쿼리가 Explain plan을 보지 않고서도이 쿼리로 고생했는지 여부를 말하기는 어렵습니다. 두 버전의 설명 계획을 수행하고 결과를 비교하는 것이 좋습니다. – Ramesh

0

그런 식으로 쿼리 문구를 사용할 수 있습니다. 나는 할 가능성이 더 높습니다 :

SELECT . . . 
FROM payment p INNER JOIN 
    (SELECT a.*, 
      ROW_NUMBER() OVER (PARTITION BY pay_key, client_id 
           ORDER BY allotment_uid 
           ) as seqnum 
     FROM allotment a 
     WHERE pay_code = 'xyz' AND deleted = 'N' 
    ) a 
    ON a.pay_key = p.pay_key AND a.client_id = p.client_id AND 
     seqnum = 1 
WHERE p.deleted = 'N' AND 
     p.date_paid >= DATE '2017-07-01' AND 
     p.date_paid < (DATE '2017-10-01') + 1; 
+0

하위 쿼리에서 rownum = 1을 사용하는 것보다 훨씬 빠르게 작동하는 이유를 설명 할 수 있습니까? – NoobSter