DataBase/Oracle

일반적인 SQL 튜닝 기법 ...

천본앵 2009. 2. 23. 10:03

1. 바인드 변수를 사용한다.

오라클은 일단 SQL 문장이 실행되면 이를 메모리에 로드한뒤 처리하는데 가정 먼저 이전에 처리된 것 중

이와 동일한 문장이 있는지 메모리에서 찾게 된다. 만약 동일한 문장이 있으면 이미 이전에 처리한 문장이

므로 파싱 단계에서 하는 문법 검사 그리고 옵티마이저가 수행하는 여러가지 작업을 건너 뛰고 이미 만들어진 실행계획대로 처리하여 결과를 반환하게 된다. 가끔씩 복잡한 복잡한 쿼리를 실행하면 맨 처음 실행할 때는 결과가 나오기까지 시간이 오래 걸리지만 두번째 부터는 결과가 빨리 나오는 경우를 볼 수 있는데,

바로 이러한 처리 방식 떄문이다.

그런데 여기서 말하는 동일한 문장은 대소문자는 물론 공백이 포함되어 있다면 이것까지 정확히 같은 문장을 의미한다. 만약 이전 문장에 대소문자는 물론 공백이 하나 추가되었다면 오라클은 다른 문장으로 인식하게 된다. 따라서 where 조건에 바인드 변수를 사용하면 비교값이 달라지더라도 동일한 문장으로 인식을 하여 처리 하지만 , 바인드 변수를 사용하지 않는다면 모두 다른 문장으로 인식하게 되므로 처리속도가 느려지게 된다.

 

2. 가급적 where 조건에서는 인덱스 컬럼을 모두 사용한다.

인덱스를 만들어 놓더라도 where 조건을 어떻게 명시하느냐에 따라 옵티마이저가 인덱스를 사용할 수 도 있고 사용하지 않을 수도 있다. 예를 들어 A 와 B라는 컬럼에 인덱스를 만들었는데, where 조건에 A컬럼만 사용한다면 인덱스를 타지 않게 된다.

 

3. 인덱스 컬럼에 사용하는 연산자는 가급적 동등 연산자(=)를 사용하라.

비록 인덱스 컬럼을 where 조건에 모두 명시하였더라도 like와 같은 연산자를 사용하면 인덱스 효율이 떨어진다. like외에도 is null, is not null, not in 등이 사용되었을 경우에도 마찬가지 현상이 발생한다.

 

4. 인덱스 컬럼은 변형하여 사용하지 않도록 한다.

where 조건에서 인덱스 컬럼을 사용했고, 동등 연산자를 사용했다 하더라도 인덱스 컬럼에 변형을 가하게 되면 인덱스를 사용하지 못한다.

 

5. OR 보다는 AND를 사용하라.

옵티마이저 OR-Expansion 처리는 OR 연산자로 연결된 쿼리를 UNION ALL로 변환하므로 OR 보다는 AND를 사용해야 성능 좋은 쿼리를 작성할 수 있다.

 

6. 그룹핑 쿼리를 사용할 경우 가급적 HAVING 보다는 where 절에서 데이터를 필터링 하라.

그룹핑 쿼리에서는 where 조건 뿐만 아니라 HAVING 절에 조건을 주어 반환하는 로우를 필터링 할 수 있다. 그룹핑 쿼리 처리순서는 where 조건이 먼저 처리 되므로 가급적 필터링 할 대상은 where 조건에서 처리할 수 있게 쿼리를 작성하도록 한다. HAVING 절은 이미 where 절에서 처리된 로우들을 대상으로 또 조건을 검사하기 때문에 좋은 성능을 발휘하기가 힘들다.

 

7. DISTINCT는 가급적 사용하지 않는다.

DISTINCT 키워드는 내부적으로 정렬 작업을 수반하기 때문에 꼭 필요한 경우가 아니라면 사용하지 않는다.

 

8. IN, NOT IN 대신 EXISTS와 NOT EXISTS를 사용하라.

where 조건에서 in 이나 not in 연산자 보다는 EXISTS나 NOT EXISTS를 사용하는 것이 더 좋은 성능을 발휘한다.

 

9. SET 연산자 사용시 UNION 대신 UNION ALL을 사용하라.

union 연산자는 연결된 쿼리에서 동일한 로우는 제거하고 한 로우만 반환하게 된다. 따라서 추가적으로 필터링하는 로직이 숨어 있으므로 union all 보다는 비용이 높을 수 밖에 없다.