[업무에 바로 쓰는 SQL 튜닝] 4.2.5 습관적으로 중복을 제거하는 나쁜 SQL 문

2024. 10. 4. 12:52CS/Database

목차

❌ 문제의 SQL 문
😎 실행 계획 살펴보기
⭕ DISTINCT 키워드를 제거해 보자
🚀 정리

 

❌ 문제의 SQL 문

요구사항 : 사원의 사원번호, 이름, 성, 그리고 부서 관리자의 부서번호를 중복 없이 조회하는 쿼리를 작성해 주세요.

select
    distinct 사원.사원번호,
    사원.이름,
    사원.성,
    부서관리자.부서번호
from 사원
join 부서관리자 on (사원.사원번호 = 부서관리자.사원번호);

 

수행 결과

총 24건이며 소요 시간은 0초에 가깝게 나왔다.

😎 실행 계획 살펴보기

1. id 값이 둘 다 1이므로 서로 조인하고 있다.

2. 부서관리자 테이블의 type이 index로 인덱스 풀 스캔을 하고 있다.

3. 사원 테이블의 type은 eq_ref으로 사원번호(PK)를 사용해 1건의 데이터를 조회하는 효율적인 방식을 사용하고 있다.

4. DISTINCT를 수행하기 위해 별도의 임시 테이블 Using temporary을 만들고 있다.

 

그럼, 어떤 부분이 문제일까?

사원테이블의 기본 키는 사원번호이다. 이 의미는 문제의 SQL문에서 SELECT절에 작성된 사원.사원번호에는 중복데이터가 없다는 뜻이다. 따라서 DISTINCT를 사용해 중복을 제거하는 건 불필요했다.

 

왜, distinct 키워드 사용이 문제가 될까?

DISTINCT 키워드는 나열된 열들을 정렬한 뒤에 중복 데이터를 삭제한다. 이미 정렬된 데이터가 아니라면 정렬 작업이 부담이 될 수 있다.

 

 DISTINCT 키워드를 제거해 보자

select
    사원.사원번호,
    사원.이름,
    사원.성,
    부서관리자.부서번호
from 사원
join 부서관리자 on (사원.사원번호 = 부서관리자.사원번호);

이전과 같이 총 24건이고 소요시간은 0초대로 변화가 없기에 소요시간을 기준으로 성능 개선 여부를 판단하기 어렵다. 이번에는 실행 계획을 통해 튜닝이 잘 되었는지 살펴보자.

 

실행 계획 확인 

Extra 항목에서 Using temporary가 삭제되었다. 이는 DISTINCT 키워드를 제거한 것과 관련이 있는데, 임시 테이블을 생성해서 추가적인 정렬과 중복 제거를 하지 않아도 된다.

 

🚀 정리

1. 임시 테이블 Using temporary이 있다면, 어떤 이유로 생성되었는지 확인해서 필요한 작업인지 살펴보자.

2. DISTINCT키워드를 사용할 때에는 중복 제거가 필요한 게 맞는지, 처음부터 중복이 없는 건 아닐지 확인하자!

- 왜? DISTINCT는 내부적으로 임시테이블을 활용하고, 정렬작업을 수행하기 때문에, 필요하지 않다면 사용하지 않는 것이 좋다.

 

 

 

출처 : [도서] 업무에 바로 쓰는 SQL 튜닝