본문 바로가기
Develop/MSSQL

2023.10.18

by 3-stack 2023. 10. 18.

1. 조인하고 그룹핑 ->그룹핑하고 조인

불필요한 rows만큼 JOIN 조건을 체크하지 않기 위해서

접기

/***** 조인하고 그룹핑 *****/
SELECT 
    COUNT(*) AS totalCnt
  , SUM(IIF(resultStatusCode = 'S1',  1, 0)) AS completeCnt
  , SUM(IIF(resultStatusCode = 'S2',  1, 0)) AS ingCnt
  , SUM(IIF(resultStatusCode = 'S-1', 1, 0)) AS absentCnt
FROM (
    SELECT RS.NEISCode, RS.IpsiYear, RS.IpsiGubun, RS.ExamSetNo, RS.SuhumNo, MAX(RR.StatusCode) AS resultStatusCode
    FROM tbRecordStuSet RS
    INNER JOIN tbRecordExamSet RE ON  RE.idx  = RS.idx
    LEFT JOIN tbRecordResult RR ON  RR.idx = RS.idx
    GROUP BY RS.NEISCode, RS.IpsiYear, RS.IpsiGubun, RS.ExamSetNo, RS.SuhumNo
) tb
GROUP BY ROLLUP tb.NEISCode, tb.IpsiYear, tb.IpsiGubun, tb.ExamSetNo


/***** 그룹핑하고 조인 *****/
SELECT MAX(totalCnt), MAX(completeCnt), MAX(ingCnt), MAX(absentCnt)
FROM tbRecordExamSet RE
INNER JOIN (
    SELECT NEISCode, IpsiYear, IpsiGubun, ExamSetNo, COUNT(DISTINCT SuhumNo) AS totalCnt
    FROM tbRecordStuSet
    GROUP BY NEISCode, IpsiYear, IpsiGubun, ExamSetNo
) RS ON  RS.idx= RE.idx
LEFT JOIN (
    SELECT NEISCode, IpsiYear, IpsiGubun, ExamSetNo
        , SUM(IIF(StatusCode = 'S1', 1, 0)) AS completeCnt
        , SUM(IIF(StatusCode = 'S2', 1, 0)) AS ingCnt
        , SUM(IIF(StatusCode = 'S-1', 1, 0)) AS absentCnt
    FROM tbRecordResult
    GROUP BY NEISCode, IpsiYear, IpsiGubun, ExamSetNo 
) RR ON   RR.idx= RE.idx
GROUP BY RE.NEISCode, RE.IpsiYear, RE.IpsiGubun, RE.ExamSetNo

image

  • 그룹핑하고 조인하는 경우 Aggregate되어 rows가 8, 8로 감소되었으면 인덱스롤 활용해 NL JOIN 하는 것을 확인할 수 있다.
  • 조인하고 그룹핑하려고 하는 경우 조인 대상인 두 데이터 집합의 rows가 14,297, 99,036으로 확인되어 인덱스가 있음에도 Merge Join 한다.

2. 릴레이션을 사용하는 것은 비용이 1이다. 최대한 활용해라

3. 프로시저 실행시 내가 넣은 string은 adhoc이라고 하는데 맞나? 맞다!

  • adhoc query가 뭔가?
    • stored procedure와 같이 DBMS에서 관리되고 있는 쿼리가 아니다. stored procedure는 미리 준비되어 있기 떄문에 실행계획 재컴파일링이 필요할때만 이뤄짐
    • EXEC, SP_EXECSQL로 동적으로 주어진 SQL을 실행한다.
    • 물론 adhoc query도 캐싱이된다. 문자열변동이 없는 경우.

4. OLAP성 대량의 데이터 조회시 Buffer Pool의 보석같은 데이터들이 밀리는거 아닌가?

우선 쿼리결과가 버퍼캐시에 올라가지 않는 경우는 없다.
DBMS에 따라 내부 처리방식이 다르지만 일반적으로 1개의 버퍼풀만 사용하는 것이 아니라 여러 버퍼풀을 사용하여, 사용빈도와 데이터 크기에 따라 용도에 맞는 버퍼풀을 사용하도록 처리된다.

댓글