2017-10-17 7 views
0

테이블에 subscription 테이블이 있고 테이블에 payments 테이블이 있습니다. 2 가지 옵션 중에서 성능을 결정하는 것이 핵심 고려 사항입니다.조인 조건이나 이전 CTE에 행 번호 필터를 추가해야합니까?

아래의 두 가지 옵션 중 성능이 더 좋은 것은 무엇입니까?

만 그룹화 모든 iddate (따라서 row_number() 분석 함수)에 대해 하나 개의 행을 얻으려면 내가 필요하고 내가 임팔라를 사용하고,이 테이블은 대형 (행의 여러 수백만)입니다.

옵션 1 :

WITH cte 
    AS (
    SELECT * 
     , SUM(amount) OVER (PARTITION BY id, date) 
     AS sameday_total 
     , ROW_NUMBER() OVER (PARTITION BY id, date ORDER BY purchase_number DESC) 
     AS sameday_rownum 
    FROM payments 
), 
payment 
AS (
    SELECT * 
    FROM cte 
    WHERE sameday_rownum = 1 
    ) 
    SELECT s.* 
     , p.sameday_total 
    FROM subscription 
    INNER JOIN payment ON s.id = p.id 

옵션 2 :

WITH payment 
    AS (
    SELECT * 
      , SUM(payment_amount) OVER (PARTITION BY id, date) 
      AS sameday_total 
      , ROW_NUMBER() OVER (PARTITION BY id, date ORDER BY purchase_number DESC) 
      AS sameday_rownum 
    FROM payments 
) 
SELECT s.* 
     , p.sameday_total 
FROM subscription 
INNER JOIN payment ON s.id = p.id 
        AND p.sameday_rownum = 1 
+1

'on' 절에 조건을 넣기 만하면됩니다. 두 개의 CTE로 쿼리를 복잡하게 만들 필요가 없습니다. –

+0

감사합니다. 따라서 내부 조인이라는 점을 감안하면 성능에 영향을 미치지 않습니다. 이 조인 조건 필터링 최종 SQL 문을 SQL 조건 자에서 where 절 필터링 대 성능이 비슷한 경우 궁금해? – cdabel

+2

쿼리 계획을보고 옵티마이 저가 처음이나 마지막에 필터를 적용 할 것인지 확인해야합니다. – Connor

답변

1

또한 존재 "0이 옵션"

나는 내 질문을 설명하기 위해 쿼리를 단축 한 . 단순히 CTE를 사용할 필요가없는 훨씬 더 전통적인 "파생 테이블".

SELECT s.* 
     , p.sameday_total 
FROM subscription 
INNER JOIN (
      SELECT * 
      , SUM(payment_amount) OVER (PARTITION BY id, date) 
       AS sameday_total 
      , ROW_NUMBER() OVER (PARTITION BY id, date ORDER BY purchase_number DESC) 
       AS sameday_rownum 
      FROM payments 
      ) p ON s.id = p.id 
        AND p.sameday_rownum = 1 

모든 옵션 0,1 2 (나는 임팔라 이상의 SQL Server에 대한 그 문에 대한 자세한 확신하지만) 동일하거나 설명 매우 유사한 계획을 생성 할 가능성이 높다.

CTE를 채택하는 것 자체가 쿼리를보다 효율적으로 또는 더 효율적으로 수행하지 않으므로 옵션 1과 2 사이의 구문 변경은 중요하지 않습니다. 특정 작업 (예 : 재귀)에 CTE를 사용하는 것을 선호하므로 옵션 0을 선호합니다.

각 옵션에서 무엇을 생산하는지 알아 보려면 use explain plans을 사용해야합니다.