[업무에 바로 쓰는 SQL 튜닝] 4.2.6 다수 쿼리를 UNION 연산자로만 합치는 나쁜 SQL문

2024. 10. 7. 21:22CS/Database

목차

❌ 문제의 SQL 문
😎 실행 계획 살펴보기
⭕ UNION ALL 연산자로 변경해 보자
🚀 정리

 

❌ 문제의 SQL 문

요구사항 : 성이 Baba이면서 성별이 M인 사원 데이터와 성이 Baba이면서 성별이 F인 사원 데이터를 합해서 조회하는 쿼리를 작성해 주세요.

select 성별, 사원번호
    from 사원
    where 성별 = 'M'
        and 성 = 'Baba'

union

select 성별, 사원번호
    from 사원
    where 성별 = 'F'
        and 성 = 'Baba';

 

수행 결과

+--------+--------------+
| 성별    |    사원번호    |
+--------+--------------+
| M      |        11937 |
| M      |        12245 |
| M      |        15596 |
| M      |        15899 |
					...
| F      |       495777 |
| F      |       496003 |
| F      |       498356 |
| F      |       499779 |
+--------+--------------+
226 rows in set (0.0019 sec)

총 226건으로 소요시간은 0초대이다. 데이터가 많지 않기에 튜닝 결과의 지표로 실행 계획을 포함해서 종합적으로 판단해 보자.

 

😎 실행 계획 살펴보기

1. id가 1,2인 행은 사원 테이블의 I_성별_성 인덱스를 사용한다.

2. id가 3인 행은 id가 1,2인 행의 결과를 통합한 뒤 중복을 제거하는 작업을 처리한다. 

- Extra의 Using temporary를 보면 메모리에 임시테이블을 생성해서 그 내부에서 union 연산 작업을 처리할 것 같다.

- 데이터가 적으면 메모리를 사용하겠지만, 결과량이 많다면 디스크에 임시파일을 생성해 union작업을 수행한다.

 

여기서는 어떤 게 문제일까?

중복 제거가 필요한 상황인지 확인할 필요가 있다!

문제의 SQL문에서 두 select문은 I_성별_성 인덱스를 활용해 데이터를 조회하므로 이미 중복이 제거된 상태이다. 따라서 추가적으로 임시 테이블을 만들어서 중복을 제거할 필요가 없다.

 

🔆 여러 개의 select문 실행 결과를 합친 후 중복 데이터를 제거하는 작업을 하는 union을 제거하고

단순히 여러 개의 select문 실행 결과를 합치는 union all로 변경해 보자. 🔆 

 

 UNION ALL 연산자로 변경해 보자

select 성별, 사원번호
    from 사원
    where 성별 = 'M'
        and 성 = 'Baba'

union all

select 성별, 사원번호
    from 사원
    where 성별 = 'F'
        and 성 = 'Baba';

 

수행 결과

+--------+--------------+
| 성별    | 사원번호       |
+--------+--------------+
| M      |        11937 |
| M      |        12245 |
| M      |        15596 |
| M      |        15899 |
           ...					
| F      |       495777 |
| F      |       496003 |
| F      |       498356 |
| F      |       499779 |
+--------+--------------+
226 rows in set (0.0016 sec)

 

총 226건이며, 소요시간은 0초대이다. 데이터가 많지 않기 때문에 소요 시간만으로 튜닝 성공 여부를 판단하기 어려우므로 실행 계획도 함께 살펴보자.

 

실행 계획 확인

1. id가 1,2인 행은 사원 테이블의 I_성별_성 인덱스를 사용한다.

2. 문제의 SQL문과 달리, id가 1,2인 결과를 단순히 합치므로 세 번째 행을 추가해 중복을 제거할 필요가 없어졌다.

 

🚀 정리

1. 데이터가 많지 않다면 실행계획까지 확인은 필수

2. 어떤 인덱스를 사용하는지 → 효율적인지, 임시 테이블을 사용하는지 → 꼭 필요한 작업인지, 확인

3. 중복을 제거하는 연산자 또는 키워드를 사용한다면, 해당 쿼리에서 중복 제거 작업이 중복인지 확인

 

 

 

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