ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 엑기스 | EXISTS 구문을 이용한 SQL 튜닝 사례
    기술이야기/엑.기.스 2021. 4. 28. 09:13

     

     

    SQL 튜닝이란?

    SQL (Structured Query Language)은 관계형 데이터베이스에서 자료 처리하는 용도로 이용하는 질의 언어이며, SQL 튜닝을 위해서는 SQL에 대한 이해와 구문에 대한 정확한 분석이 필요합니다. 이번 엑기스에서는 여러 튜닝 사례 중에서 EXISTS 구문을 이용한 튜닝 사례를 소개하겠습니다.

     

    테이블 및 INDEX 정보

     

     

    [TB_CODE] 테이블에는 10건의 데이터, [TB_DATA11] 테이블에는 약 100만 건의 데이터가 누적되어 있습니다. [TB_CODE] 테이블에 [code] 컬럼을 키, [TB_DATA11] 테이블에는 [code, date] 컬럼을 키로 Non-Clustered Index가 구성되어 있습니다. 사용자의 요구 사항이 “[TB_CODE] 테이블의 [code] 값 중에서 [TB_DATA11] 테이블에 값이 존재하는 2020년 1월 이후의 [code] 값만 출력하고 싶다”라고 한다면 SQL 구문은 다음과 같이 작성할 수 있습니다.

     

    SQL 구문 및 실행계획

    SELECT A.code
    FROM TB_CODE A INNER JOIN TB_DATA11 B 
    ON A.code=B.code
    AND B.date >'20200101'
    GROUP BY A.code
    ORDER BY A.code
    GO

     

     

     

    구문의 경우 사용자의 요구 사항에 맞도록 작성되었지만 실제 수행된 실행계획을 해석하면 “[TB_CODE] 테이블을 기준으로 [TB_DATA11] 테이블과 [code] 컬럼으로 조인한 다음 조인 결과 집합의 [code] 값을 GROUP BY 하여 중복 값을 제거하고 조회한다”라고 볼 수 있습니다. 최종 결과 건수는 7건임에도 불구하고 45만 건의 데이터를 읽고 이를 GROUP BY 하여 중복제거하는 로직은 불필요한 IO를 발생하는 요인이기 때문에 최적화가 필요합니다. 더 나아가 해당 계획은 NL 조인(Nested Loop Join)으로 수행되었습니다. NL 조인 특성상 선행 테이블 건수만큼 후행 테이블에 조인 시도를 하기 때문에 선행 테이블 건수가 많을수록 많은 IO를 발생하는 요인입니다. 그럼 해당 구문에 대한 최적화는 어떻게 진행되어야 할까요?

     

    [TB_CODE] 테이블의 [code] 값이 [TB_DATA11] 테이블에 존재하는지만 확인하면 되기 때문에 EXISTS절을 고려해 볼 수 있습니다. EXISTS는 내부적으로 세미 조인(Semi-Join)으로 수행되며 메인 쿼리 하나의 행에 대해서 서브 쿼리의 모든 행과 조인하는 방법이 아닌, 처음 조인에 성공하는 행을 만나면 더 이상 조인하지 않고 해당 행을 최종 결과 셋에 포함하기 때문에 불필요한 IO를 최소화할 수 있습니다.

     

     

     

    EXISTS절을 고려한 SQL 구문으로 변경하려면, [TB_CODE] 테이블과 [TB_DATA11] 테이블을 내부 조인하여 집계하는 구문을 서브 쿼리인 EXISTS절로 변경하면 됩니다. 변경된 SQL 구문은 메인 쿼리의 결과 집합인 10건의 행을 서브 쿼리와 조인하면서 존재 유무만 확인하면 되기 때문에 IO가 개선되며 변경된 SQL 구문은 다음과 같습니다.

     

    변경된 SQL 구문 및 실행계획

    SELECT A.code
    FROM TB_CODE A
    WHERE EXISTS (   SELECT '1'
                            FROM TB_DATA11 B
                            WHERE A.code=B.code
                            AND B.DATE >'20200101' )
    GROUP BY A.code
    ORDER BY A.code
    GO

     

     

     

    변경 전 실행계획과 비교해보면, 후행 테이블 결과 Rows가 약 45만 건에서 7건으로 줄어든 것을 확인할 수 있습니다. 즉, 선행 테이블 10건에 대해 후행 테이블 [code] 값과 일치하는 행이 있으면 결과 셋에 포함하고 이후 불필요한 데이터는 읽지 않고 바로 선행 테이블의 다음 값을 비교하기 때문에 IO 감소 효과를 볼 수 있습니다.

     

    개선효과

     

     

     

    마치며...

    엑셈의 SQL Server팀은 MaxGauge for SQL Server뿐만 아니라 튜닝 및 컨설팅도 지원하고 있습니다. 최근에는 SQL 성능 이슈 관련 튜닝 도서도 올해 출간 준비 중이니 많은 관심 부탁드립니다!

     

     

     

     

     

     

     

     

     

     

    기고 | 신기술본부 신대원

    편집 | 사업기획팀 김소정

     

     

     

     

     

     

     

    댓글 0

© Copyright 2001 ~ 2021 EXEM CO., LTD. All Rights Reserved