권순용의 DB 이야기
우리가 수행하는 SQL은 변한다. 1부. 1 12 99,999+

by axiom 구문분석 소프트 파싱 Soft Parsing 하드 파싱 Hard Parsing Query Transformation Transitivity 쿼리변환 [2013.01.08]


우리가 수행하는 SQL은 더 이상 그대로 수행되지 않는다. 이와 같다는 사실을 인지하는 사람에게는 놀라운 사실이 아니지만 이를 처음 듣는 사람은 놀랄 수밖에 없을 것이다.

그렇다면 이와 같이 SQL이 변형되어 전혀 다른 SQL이 수행된다면 원하는 데이터를 추출할 수 없지 않을까 하는 고민을 할지도 모른다. 하지만, 이와 같이 SQL이 변형되더라도 동일한 데이터가 추출된다는 것은 데이터베이스의 옵티마이저가 보장하게 된다.

애플리케이션에서 수행하는 SQL은 왜 변하는 것일까?

이런 현상은 데이터베이스의 버전이 높아질수록 더욱 심하게발생한다. 그렇다면 우리는 어떻게 믿고 SQL을 수행할 수 있겠는가?

SQL이 변경 될지라도 결과는 동일하다는 것을 데이터베이스는 보장하게 된다. 그렇기 때문에 더 이상 추출되는 결과를 의심할 필요는 없을 것이다. 그렇다면 이것으로 모든 것이 끝인가?

그렇지는 않다. SQL이 어떻게 변경되는지에 따라 SQL의 성능은 천차만별이 된다는 것을 많은 사람들이 알고 있을 것이다.

그렇기 때문에 우리는 SQL이 어떻게 변경되는가를 인지해야만 할 것이다. 그래야만 우리가 원하는 성능을 보장받을 수 있게 된다.

SQL이 수행되는 방법을 인지하자

SQL의 수행에서 가장 먼저 발생하는 단계는 구문 분석이다. 구문 분석은 어떤 절차를 수행하게 되는가?

이제부터 구문 분석의 수행 절차에 대해 확인해 보자.

  • - 동일한 SQL의 수행 여부 확인
  • - 문법/철자 확인
  • - Semantic 확인
  • - 권한 확인

기존에 동일한 SQL의 수행 여부를 확인하는 과정이 구문 분석의 첫 번째 단계다.

구문 분석 단계에서 어느 한 곳이라도 문제가 발생한다면 해당 SQL은 수행하지 못하고 에러를 발생시키게 된다.

동일한 SQL이 이전에 수행되었는지를 메모리에서 확인하여 기존에 수행된 SQL이며 실행 계획 등의 실행 정보가 메모리에 저장되어 있다면 해당 정보를 재사용하게 된다. 이를 소프트 파싱(Soft Parsing)이라고 한다.

메모리에 해당 SQL에 대한 실행 정보가 존재하지 않는다면 해당 SQL에 대한 구문 분석을 새로 시작해야 할 것이다. 이를 하드 파싱(Hard Parsing)이라고 한다.

두 번째로 문법 및 철자 확인 작업을 통해 SQL이 문법에 맞는지 또는 철자가 잘못된게 없는지를 확인하게 된다. 해당 단계에서 문제가 발생하면 Syntax 에러 메시지를 발생시키게 된다.

세 번째로 Semantic 확인 단계를 수행하게 된다. Semantic 확인 단계는 Database Resolution 단계라고도 말한다. 해당 단계는 SQL에 사용된 테이블과 테이블의 컬럼이 실제 데이터베이스에 존재하는 지를 확인하게 된다.

네 번째로는 해당 SQL을 수행할 수 있는 권한이 있는지를 확인하게 된다. 권한이 있다면 해당 SQL을 수행할 수 있게 되고 권한이 없다면 권한 관련 에러가 발생하게 된다.

이와 같이 SQL은 여러 단계를 수행한 후 하나의 단계도 이상이 없는 경우에만 해당 SQL이 수행된다.

SQL은 옵티마이저에 의해 변경된다

SQL이 구문 분석을 수행하는 중간에 해당 SQL을 변경하는 단계가 존재한다. 이와 같은 단계를 Query Transformation이라고 한다. 이와 같은 Query Transformation은 다음과 같은 단계로 구성된다.

  • - Transitivity
  • - 뷰 Merging
  • - 서브쿼리 Merging
  • - OR Expansion
  • - Query Rewrite

SQL을 변경하는 단계로 뷰 Merging, 서브쿼리 Merging, Transitivity, OR Expansion 및 Query Rewrite 과정을 수행한다. 이 단계는 옵티마이저가 단독으로 수행하는 과정이다.

그렇다면 이와 같은 Query Transformation은 왜 발생하는 것일까? 우리가 작성한 SQL은 결과도 달라지지 않는데 옵티마이저는 왜 SQL을 변경하여 수행하는 것일까?

그 이유는매우 간단하다. SQL의 성능을 최적화하기 위한 옵티마이저의 노력인 것이다.

결국, 이와 같은 Query Transformation은 처리 범위를 감소시키는 조건을 찾아내어 인덱스가 존재한다면 최대한 처리 범위를 감소시키고자 하는 옵티마이저의 노력인 것이다.

이와 같은 현상은 데이터베이스 버전이 높아지면 높아질수록 더욱 빈번하게 발생하게 될 것이다.

Transitivity를 이해하자

Transitivity는 무엇을 의미하는가? Transitivity는 Query Transformation 중 가장 쉬운 변형에 해당된다. 다음 예제를 확인해 보자.

SELECT 사원.사원번호, 사원.사원이름, 부서.부서번호, 부서.부서이름
  FROM 사원, 부서
 WHERE 사원.부서번호 = 부서.부서번호
   AND 부서.부서번호 = '10';

위의 예제는 재미있는 사실이 하나 존재한다. 과연 무엇이재미있는 사실인가?

바로 부서.부서번호 ='10'인 조건이다. 해당 SQL에서 부서 테이블의 부서번호 조건이 값이'10'이라면 사원 테이블의 부서번호 조건의 값은 얼마인가?

조인 조건이 사원.부서번호 = 부서.부서번호이므로 부서.부서번호= '10'에 의해 사원 테이블의 부서번호 조건도'10'인 값이된다.

이는 마치 수학의 삼단 논법과 같은 이야기다. 결국, 자명한 사실이라는 것이다. 이를 옵티마이저도 알고 있기 때문에 아래와 같이 SQL을 다시 작성하게 된다.

SELECT 사원.사원번호, 사원.사원이름, 부서.부서번호, 부서.부서이름
  FROM 사원, 부서
 WHERE 사원.부서번호 = 부서.부서번호
   AND 부서.부서번호 = '10'
   AND 사원.부서번호 = '10';

위와 같이 사원.부서번호 조건을 추가하여 SQL을 수행하게 된다.

사원 테이블도 처리 범위를 감소시킬 수 있는 조건이 추가되는 것이므로 상황에 따라서는 성능에 유리할 수 있을 것이다. 이와 같은 현상을 SQL의 Query Transformation 단계 중 Transitivity 단계라고 말한다.

결국, Transitivity 단계는 논리적으로 이상이 없는 조건을 추가하여 처리 범위를 감소시켜 성능을 최적화하고자 하는 옵티마이저의 노력인 것이다.

Transitivity는 아래와 같은 특징을 가진다.

  • - 점(=) 조건은 Transitivity 가능
  • - 선분 조건은 Transitivity 불가능
  • - 조인 조건은 transitivity 불가능

Transitivity는 아쉽게도 =로 논리적인 조건만을 추가하게되며 조인 조건 또는 선분 조건인 경우에는 조건을 추가하지 못하게 된다.

Query Transformation은 이처럼 SQL의 처리 범위를 최소화시켜 성능을 향상시키고자 하는 옵티마이저의 노력임에는 틀림 없다.

이제라도 이와 같은 옵티마이저의 노력을 이해하는 것이 중요하다. 다음 강의에서는 Transitivity의 상세한 예제와 Query Transformation에 대해 좀더 자세히 확인해 보도록 하겠다.

- 강좌 URL : http://www.gurubee.net/lecture/2242

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

by 이연호 [2013.01.08 23:27:18]
좋은글 감사합니다    

by 아발란체 [2013.01.09 08:56:04]

보물 같은 자료네요.
점선에 대한 이해를 보다 할 수 있었습니다.


by 강군 [2013.02.23 10:26:51]

만든사람아니면 알기힘든 정보네요..감사합니다^^


by love123 [2013.04.23 10:16:36]

풀어쓰니 이해가 잘되었습니다~
감사합니다~

by 손님 [2013.08.20 22:02:45]
감사합니다

by 암드 [2013.10.23 13:36:43]

좋은글 감사합니다.


by 시그너스7000 [2014.03.22 20:42:07]

 감사합니다


by 참된신자 [2014.07.31 17:33:00]

감사합니다 :)


by 헬로헬로일 [2014.10.12 03:26:31]

좋은정보 감사요 ^^


by 이주열 [2015.01.06 12:23:51]

좋은글 감사합니다.


by 주년 [2018.01.22 15:49:45]

좋은글 감사합니다


by Bug [2018.11.28 12:59:04]

공부 많이되네요 ㅋㅋ

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입