우리가 수행하는 SQL은 변한다
우리는 변화에 익숙해 있지는 않다. 특히, 우리가 의도하지 않았음에도 불구하고 SQL이 변경되는 것에는 대부분의 사람들이 익숙해 있지 않은 것이 사실이다. 하지만, 이제 우리는 이와 같이 SQL이 변하는 것에 익숙해져야만 한다. 왜 익숙해져야 하는 것인가? 그것은 우리가 사용하는 SQL의 많은 부분이 변하기 때문이다.
인라인 뷰는 실제 SQL을 작성하는 단계에서 많이 사용하게 된다. 많은 개발자들은 원하는 데이터를 추출하기 위해 인라인 뷰를 많이 사용하는 것이 현실이다. 하지만 대부분의 개발자들은 자신이 작성한 인라인 뷰가 변하는지 작성한 그대로 수행되는지를 인지하지 못하는 경우가 대부분이다. 이와 같이 SQL을 작성해도 우리는 원하는 데이터를 추출할 수는 있지만 원하는 성능을 보장받기는 쉽지 않을 것이다.
SQL의 첫 번째 목적은 필요한 데이터를 정확히 추출하는 것임에는 틀림 없다. 하지만 원하는 데이터라 할지라도 그 데이터를 추출하는 데 많은 시간이 소요된다면 과연 우리가 업무를 하면서 해당 데이터를 확인하게 될까? 대부분의 경우는 성능이 저하되는 SQL에 대해서는 사용하지 않게 되므로 아무리 필요한 데이터를 추출할지라도 성능을 보장하는 것은 매우 중요한 것이다. 이번 호에서는 우리가 수행하는 SQL은 변한다의 마지막인 인라인 뷰가 변하지 않는 경우를 확인해 보자.
인라인 뷰는 수학의 괄호
인라인 뷰는 실행 방식에 의해 주 쿼리의 조건이 인라인 뷰에서 사용되는 경우와 인라인 뷰에서 사용되지 않는 경우의 두 가지 종류가 존재한다. 결국, 다음과 같이 인라인 뷰의 종류가 존재하게 된다.
● Mergeable 인라인 뷰
● Non-Mergeable 인라인 뷰
Non-Mergeable 인라인 뷰는 뷰 Merging이 발생하지 않는 인라인 뷰이다. 이와 같은 인라인 뷰는 어떻게 수행되는 것일까?
이 SQL에서 WHERE 문의 GRADE 조건이 인라인 뷰 안으로 삽입된다면 뷰 Merging이 발생하여 Mergeable 인라인 뷰로 수행되게 된다. 이와 같은 경우 EMPLOYEES 테이블에 GRADE+SAL 인덱스가 존재한다면 해당 인덱스를 이용할 수 있게 된다. 그렇다면 뷰 Merging이 발생하지 않는 Non-Mergeable 인라인 뷰로 수행된다면 어떻게 되겠는가? Non-Mergeable 인라인 뷰로 수행된다면 이는 수학의 괄호와 같다.
수학의 괄호와 비교해 보자. 수학의 괄호는 우선순위를 정하게 된다. 그렇기 때문에 괄호가 사용된 부분은 별도로 수행하게 된다. Non-Mergeable 인라인 뷰는 수학의 괄호와 같다. 그렇기 때문에 EMPLOYEES 테이블에 GRADE+SAL 인덱스가 존재하더라도 해당 인덱스를 이용할 수 없게 된다. 이는 주 쿼리의 조건인 GRADE 조건이 Non-Mergeable 인라인 뷰에서는 인라인 뷰로 삽입되지 못하기 때문에 해당 조건이 처리 범위를 감소시키는 조건으로 사용될 수 없기 때문이다.
결국, 인라인 뷰가 별도로 수행되는 현상이 발생하는 것이 Non-Mergeable 인라인 뷰가 되며 이는 수학의 괄호와 같이 인라인 뷰의 괄호가 연산자의 순서를 결정하는 역할을 수행하게 된다.
Non-Mergeable 인라인 뷰 확인하기
그렇다면 우리가 인라인 뷰만을 보고 어떻게 뷰 Merging이 발생하는지 아닌지를 확인할 수 있겠는가? 물론, SQL의 형태만을 보고 판단할 수는 없다. 하지만, 다음과 같은 문법이 SQL에 사용된다면 Non-Mergeable 인라인 뷰가 되거나 Mergeable 인라인 뷰가 되더라도 주 쿼리의 조건이 인라인 뷰로 삽입되는 현상이 발생된다.
● UNION ALL
● UNION
● DISTINCT
● GROUP BY
● ROWNUM
● 집합 함수
이와 같은 문법을 사용한다면 해당 SQL은 주 쿼리의 조건이 인라인 뷰 안으로 삽입되거나 Non-Mergeable 인라인 뷰로 수행될 가능성이 높다. 물론, 해당 문법을 사용한 인라인 뷰는 인라인 뷰가 주 쿼리와 합쳐지는 형태의 뷰 Merging이 발생하지 않는다. 하지만, 이와 같은 것만으로 우리가 Mergeable 인라인 뷰인지 Non-Mergeable 인라인 뷰인지를 판단할 수는 없다. 그렇다면 어떻게 우리는 정확히 Non-Mergeable 인라인 뷰인지 아닌지를 판단할 수 있을까? 이는 해당 SQL의 실행 계획을 통해 확인해야 한다. 해당 SQL의 실행 계획을 확인해 보자.
이렇게 하면 VIEW 실행 계획이 생성된다. VIEW 실행 계획이 생성된다면 이는 인라인 뷰가 별도로 수행되어 메모리에 해당 데이터를 생성하는 것이다. 이는 마치 인라인 뷰가 수학의 괄호와 같이 수행되는 것이다. 결국, 실행 계획에 VIEW 실행 계획이 생성된다면 이는 인라인 뷰가 별도로 엑세스되는 것이므로 Non-Mergeable 인라인 뷰로 수행되는 것이다. 그렇기 때문에 VIEW 실행 계획이 생성되지 않는다면 이는 Mergeable 인라인 뷰로 수행되는 형태가 된다. 여기서의 Mergeable 인라인 뷰는 인라인 뷰가 주 쿼리와 합쳐지는 형태의 Mergeable 인라인 뷰로 수행되는 것이다. 만약, Mergeable 인라인 뷰 중 주 쿼리의 조건이 인라인 뷰 안으로 삽입된다면 실행 계획은 어떻게 수행되겠는가? 이와 같다면 실행 계획에는 VIEW PREDICATE라는 실행 계획이 VIEW 실행 계획 위치에 생성되게 된다.
앞서 실행 계획을 통해서 우리는 뷰 Merging이 발생했는지 발생하지 않았는지를 판단할 수 있게 된다. 이런 이유 때문에 인라인 뷰를 작성하면서 해당 SQL의 실행 계획 확인은 매우 중요하다. 하지만 아직도 많은 곳에서는 이와 같이 인라인 뷰에 대한 실행 계획을 확인하지 않는 것이 대부분이다. 이제라도 인라인 뷰에 대한 실행 계획을 확인하는 습관을 가지는 것은 매우 중요하다.
우리가 작성하는 SQL은 언젠가 변할 수 있다는 것을 명심하길 바란다. 변하는 SQL을 예측하여 그에 최적인 형태를 준비하는 것이 우리가 할 수 있는 최선의 방법이다.
필자소개
권순용 oksy@axiominfo.co.kr|(주)엑시엄 대표이사이며 성능 최적화, 데이터 모델링 및 아키텍쳐를 전문적으로 한다. 성능 최적화에 대한 특허를 출원했으며 저서로는 Perfect 오라클 실전 튜닝, 초보자를 위한 오라클 10g 및 Inside SQL 등이 있다. 또한, 후배 양성 및 전문가 양성에도 많은 관심을 가지고 있다.
출처 : 한국 마이크로 소프트웨어 [2009년 2월호]