1. 비효율적인 MINUS 대신 NOT EXISTS를 사용하기
MINUS : 어느 한 집합에 있는 데이터 중 다른 집합에 존재하지 않는 데이터를 추출하는 방식
- MINUS를 사용한 SQL이 성능 문제가 발생할 경우, SQL을 변경하지 않고, 성능을 개선하기가 쉽지않다.
- 차 집합을 추출하기 위해서는 MINUS 연산보다 NOT EXISTS 가 더 효율적이다.
ex )
--MINUS
select...
from A MINUS
select from B
--NOT EXISTS
select...
from A
where NOT EXISTS (
select...
from B where B.XX = A.XX )
위와 같은 2개의 쿼리문 실행시,
MINUS의 경우
- 테이블 A 데이터 추출 -> 추출된 데이터 SORT 연산 -> 테이블 B 데이터 추출 -> 추출된 데이터 SORT 연산 -> 추출된 두 개의 데이터 비교 후 최종 데이터 추출
- 수행순서가 변경 불가능하다.
- 성능면에서 떨어지게된다.
NOT EXISTS의 경우
- 데이블 A 데이터 추출 -> 추출한 데이터와 서브 쿼리 테이블 B 데이터와 비교 후 최종 데이터 추출
- 수행순서 변경이 가능하다.
- 성능면에서 비교적 유리하다.
(1) MINUS를 사용한 SQL에서 발생하는 성능 문제
- 비교 대상 테이블에서 데이터 추출하는 방식이 비효율 (Full Table Scan) 인데도 불구하고조회 조건이 없어 개선을 하기 힘들다.
- 비교 대상 테이블에서 많은 데이터가 추출되면 정렬 작업이 과다하게 발생한다.
(2) NOT EXISTS 를 이용하였을때의 위험성
- Select 절에 나열된 컬럼의 조합이 Unique 하지 않다면, NOT EXISTS를 활용 시 중복된 값이 추출될 가능성이 있다.
- 중복된 값이 나올수 있기때문에 DISTINCT 처리를 하게 되는 경우가 발생한다.
- MINUS를 무조건 NOT EXISTS로 변경한다면, 성능은 개선되겠지만 데이터 정합성이 훼손되는 현상이 발생할 수 있다.
- 그러므로 MINUS 대신 NOT EXISTS 를 사용하여 SQL을 작성할 경우 DISTINCT를 무조건 적용하기 보다는, Select 절에 나열된 컬럼 조합이 Unique 한지 먼저 판단해야한다.
- 반드시 Unique 하지 않은 경우에만 DISTINCT를 사용할것
2. 조인 대신 서브쿼리를 활용하기
- 조인 사용시에 Unique 한 컬럼을 조인하여 조회할 시 비용이 크게 들지않지만,
Unique한 컬럼과 그렇지 않은 컬럼을 조인하여 조회하게되면, 비용이 커지게 된다. - 해결방법으로는 조인순서 변경이있지만, 불가능하다.
- 처음부터 중복 값을 추출하지 않는다면, 조인 연결 시도횟수가 줄어들어 비효율을 개선할수있다.
- 데이터가 급격히 증가하게 된 조인부분을 서브쿼리로 대체하여 데이터 정합성을 훼손하지않는 선에서 효율적으로 개선할수있다.
- 단, SUM 이나 COUNT 등의 그룹 함수를 수행하는 경우는 데이터가 훼손될 수 있으므로, 데이터 정합성 체크를 필히 수행해야 한다.
3. WHERE 절의 서브쿼리를 조인으로 변경하기
- Where 절에 서브쿼리가 많다면, 서브쿼리들이 가질 수 있는 모든 조합에 대한 Cost를 계산해야 하므로, 옵티마이저가 모든 서브쿼리를 Unnest 수행한 것과 모두 수행하지 않은 것 두가지의 Cost만 계산하게 되므로 부하가 될 수 있다.
- 서브쿼리로 작성된 부분을 인라인 뷰로 바꾸어 SQL을 작성하고, 추출 데이터가 중복 값을 가진 경우에는 DISTINCT를 부여해 중복을 제거
- 인라인 뷰로 바뀐 서브쿼리를 조인 순서를 조절하는 LEADING 힌트를 사용하여 실행계획을 제어하면 의도한 대로 SQL 수행가능
'SQL 튜닝의 시작' 카테고리의 다른 글
[ SQL ] 스칼라 서브쿼리의 특성 (0) | 2021.04.03 |
---|---|
[ SQL ] 서브쿼리 동작방식 이해하기 (0) | 2021.03.07 |
[ SQL ] 서브쿼리에 대한 기본내용 이해하기 (0) | 2021.03.05 |