원문

[개발자를 위한 인덱스 생성과 SQL 작성 노하우 이병국 글봄크리에이티브 - 교보문고 (kyobobook.co.kr)](http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788996560081)

indexBook

공정쿼리

공정쿼리란 누구나 쉽게 쿼리를 작성하고 이해하는 것을 목표로 한다. 각 개발자는 본인이 작성한 쿼리를 다른 개발자가 보기 쉽게 할 수 있도록 공정하게 쿼리를 작성해야 한다.

무엇을 조회할지에 대한 쿼리 결과도 중요하지만 어떻게 조회할지에 대한 쿼리 과정도 중요하다. 한마디로 공정쿼리는 무엇을 어떻게 조회할지에 대한 내용이 모두 포함되어야 한다. 공정쿼리로 쿼리 결과뿐 아니라, 생성해야할 인덱스 정보와 접근돼야 할 실행계획 정보까지 모두 알 수 있다.

공정쿼리 작성법

공정쿼리로 작성을 안한 쿼리를 먼저 본다.

SELECT *
FROM 고객, 주문, 부서
WHERE 고객.고객번호 = 주문.주문번호
AND 주문.부서번호 = 부서.부서번호(+)
AND 고객.고객명 LIKE ?
AND 고객.성별 = ?
AND 주문.상품코드 = ?
AND 주문.주문일자 = ?
AND 주문.배송여부 = ?
AND 부서.사용여부(+) = ?

공정쿼리과정

테이블 접근 순서 고객 -> 주문 -> 부서

조인절 접근 방향: 2번 컬럼 -> 1번 컬럼, 3번 컬럼 -> 4번 컬럼

인덱스 생성 위치: 5번 컬럼(상품코드 + 주문일자), 1번 컬럼(고객번호), 5번 컬럼(부서 번호)

이를 공정쿼리로 알아보기 쉽게 만들기위해 다음과 같은 규칙을 기반으로 재작성을 한다.

  1. SELECT 절 규칙 : 접근하고자 하는 테이블의 순서대로 조회 컬럼을 나열한다.
  2. FROM 절 규칙 : 접근하고자 하는 테이블을 순서대로 나열한다.
  3. JOIN 절 규칙 : 접근하고자 하는 테이블 순서대로 조인절을 나열한다.
  4. WHERE 절 규칙 : 접근하고자 하는 테이블의 순서대로 조건절 컬럼을 나열한다.

다음과 같이 작성할 수 있다.

SELECT *
FROM 주문, 고객, 부서 -- 테이블 접근 순서
WHERE 주문.고객번호 = 고객.고객번호 -- 조인절 우측에 인덱스 생성
AND 주문.부서번호 = 부서.부서번호(+) -- 조인절 우측편 컬럼에 인덱스 생성
AND 주문.상품코드 = ? -- 첫번째 접근 테이블의 조건절에 인덱스 생성
AND 주문.주문일자 = ? -- 첫번째 접근 테이블의 조건절에 인덱스 생성
AND 주문.배송여부 = ?
AND 고객.고객명 LIKE ?
AND 고객.성별 = ?
AND 부서.사용여부(+) = ?

우리는 결론적으로 공정쿼리로 작성된 쿼리에서 다음과 같은 정보를 알 수 있다.

  1. 테이블의 접근 순서를 알 수 있다. (실행계획 정보)
  2. 조인절의 우측편 컬럼에 인덱스가 생성돼야 함을 알 수 있다. (인덱스 정보)
  3. 첫 번째 조건절 컬럼에 인덱스가 생성돼야 함을 알 수 있다. (인덱스 정보)

공정쿼리 기본 규칙에 따라 작성한 쿼리에서 얻는 정보는 모든 쿼리에서 적용되는 것은 아니지만 대부분 쿼리에 해당하므로 아주 중요한 의미를 가진다. 지금까지 다른 개발자가 작성한 쿼리에 대한 이해에 많은 시간이 필요했지만 공정쿼리 기본 규칙에 근거해 작성된 쿼리라면 누구라도 쿼리 작성자의 의도를 쉽게 알 수 있다.

공정쿼리로 작성한 쿼리는 기본적인 튜닝은 완료된 것이라 보면 틀림이 없다. 단지 2가지 측면에서 확인할 필요는 있다.

첫째, 인덱스가 있어야 할 위치에 실제로 인덱스가 존재하는지 확인한다. 존재하지 않는다면 생성해야 할 것이다.

둘째, 우리가 생각하는 테이블 접근순서와 오라클 옵티마이저의 테이블 접근 순서가 일치하는지 확인한다. 일치하지 않으면 힌트절을 추가해 올바른 테이블 순서로 유도해야한다.