DB

Scala Subquery vs Left Outer Join

창욱씨 2020. 3. 30. 14:22
728x90

Subquery란

Subquery란 다른 하나의 SQL문장의 절에 중첩된 select 문장입니다. Select, update, delete, insert와 같은 DML 문과 create table 또는 view에서 이용 가능합니다. Subquery는 알려지지 않은 조건에 근거한 값들을 검색하는 select 문장을 작성하는데 유용합니다. Subquery는 Main Query가 실행되기 이전에 한번 실행되고 SubQuery의 결과는 Main Query에 의해 사용됩니다.

Outer Join이란

Outer Join이란 Join하는 여러 테이블에서 한 쪽에는 데이터가 있고, 한 쪽에는 데이터가 없는 경우, 데이터가 있는 쪽 테이블의 내용을 모두 출력하는 것입니다. 즉, 조건에 맞지 않아도 해당하는 행을 출력하고 싶을 때 사용할 수 있습니다.

Left Outer Join
Join문의 왼쪽에 있는 테이블의 모든 결과를 가져온 후 오른쪽 테이블의 데이터를 매칭합니다. 만약 매칭되는 데이터가 없는 경우, NULL로 표시합니다.

Right Outer Join
Join문의 오른쪽에 있는 테이블의 모든 결과를 가져온 후 왼쪽 테이블의 데이터를 매칭합니다. 만약 매칭되는 데이터가 없는 경우, NULL로 표시합니다.

Full Outer Join
Left Outer Join과 Right Outer Join을 합친 것으로, 양쪽 모두 조건이 일치하지 않는 것까지 모두 결합해 출력합니다.

Scala Subquery vs Left Outer Join

Scala Subquery

함수처럼 한 레코드 당 정확히 하나의 값만을 리턴하는 Subquery입니다. 기본적으로 Outer Join이 적용되어 있습니다. 예를 들어 아래와 같은 쿼리문이 있습니다.

SELECT A.PKID
    , A.TITLE
    , NVL(B.NAME, '탈퇴한 회원'), B.NAME
    , (SELECT COUNT(*) FROM REPLY WHERE P_PKID = B.PKID) AS COUNT1
FROM BOARD B LEFT OUTER JOIN MEMBER M
    ON B.MEM_NO = M.PKID

이 쿼리를 개발환경에서 실행하면 아무런 문제가 없습니다. 그러나 데이터의 양이 많으면 많아질수록 느려지는 현상이 나타납니다. 일반적으로 Scalar Subquery를 위와 같이 쓰는 경우는 Where절에서 반복해서 들어가는B.PKID와 같은 값이 동일한 값, 혹은 거의 변하지 않는 값일 때입니다. Scala Subquery는 쿼리 수행 횟수를 최소화하기 위해서 입력값과 출력값을 내부 캐시에 저장합니다. Scala Subquery가 실행될 때 일단 입력값을 내부 캐시에서 찾아보고 존재한다면 해당하는 출력값을 리턴합니다. 내부 캐시에 없을 때만 재수행하는 것입니다. 위의 Scalar Subquery는 쿼리가 수행될 때마다 B.PKID 값이 계속 달라지는 경우입니다. 그래서 데이터가 많아질수록 속도가 느려질 수밖에 없습니다. 그래서 이를 고치기 위해 Left Outer Join을 사용했습니다.

SELECT A.PKID
    , A.TITLE
    , NVL(B.NAME, '탈퇴한 회원')
    , NVL(R.COUNT1,0)
FROM BOARD B LEFT OUTER JOIN MEMBER M
    ON B.MEM_NO = M.PKID
    LEFT OUTER JOIN (SELECT COUNT(*) COUNT1, P_PKID FROM REPLY GROUP BY P_PKID) R
    ON B.PKID = R.P_PKID

PS. Join을 할 때, 조건이 있다면 미리 조건을 건 테이블과 Join을 하면 성능이 더 나아집니다. 그 이유는 조건에 걸러진 테이블을 만드는 것과 다 만들어진 테이블을 다시 한번 조건에 따라 탐색하는 것은 비용이 다르기 때문입니다.

참고: https://eastglow.github.io/data-base/2017/12/23/%EA%B3%B5%ED%86%B5-Scala-Subquery-vs-Left-Outer-Join.html

728x90