본문 바로가기
SQL 튜닝/SQL 문 단순 수정

[SQL 튜닝] 다수 쿼리를 UNION 연산자로만 합치는 나쁜 SQL 문

by Johnny's 2023. 7. 14.

다수 쿼리를 UNION 연산자로만 합치는 나쁜 SQL 문

현황 분석

| 튜닝 전 실행 계획 |

SELECT 문을 UNION 연산자로 합치는 쿼리문

EXPLAIN
SELECT 'M' AS 성별, 사원번호
	FROM 사원
	WHERE 성별 = 'M'
	AND 성 = 'Baba'
	
	UNION
	
SELECT 'F' AS 성별, 사원번호
	FROM 사원
	WHERE 성별 = 'F'
	AND 성 = 'Baba';

- SQL문 결과 : 총  226건의 결과 출력, 1.5ms 소요

- 마지막 key가 NULL인 세번째 행에서는 id가 1인 행과 2인행의 결과를 통합하여 중복을 제거하는 작업을 처리

- 메모리에 임시 테이블을 생성(Extra 항목의 Using temporary)하고 그 내부에서 각 결과의 UNION 연산 작업을 수행

- 만약 메모리에 상주하기 어려울 만큼 id가 1인 행과 id가 2인 행의 결과량이 많다면, 메모리가 아닌 디스크에 임시 파일을 생성하여 UNION 작업을 수행 

 

튜닝 수행

WHERE 절에 성별 열과 성 열이 동등(=) 조건으로 작성되어 있음

성별 열성 열정의된 I_성별_성 인덱스를 활용하여 데이터를 빠르게 조회

2개의 SELECT 문이 UNION 연산자로 통합되는 과정에서 각 SELECT 문의 결과를 합친뒤 중복을 제거하고 결과 출력

이미 사원번호라는 기본 키가 출력되는 SQL 문에서 중복을 제거하는 과정은 불필요할 수 있음

SHOW INDEX FROM 사원;

기본 키 : 사원번호 열

I_입사일자 인덱스 : 입사일자 열

I_성별_성 인덱스 : '성별 + 성' 열

 

튜닝 결과

| 튜닝 후 실행 계획 |

사원 테이블의 사원번호 열이 키본 키라서 중복된 데이터가 출력될 수 없으므로 DISTINCT 키워드 제거

EXPLAIN
SELECT 'M' AS 성별, 사원번호
	FROM 사원
	WHERE 성별 = 'M'
	AND 성 = 'Baba'
	
	UNION ALL
	
SELECT 'F' AS 성별, 사원번호
	FROM 사원
	WHERE 성별 = 'F'
	AND 성 = 'Baba';

1.5ms → 0.6ms (매우 근소한 차이)

id가 1,2인 결과를 단순히 합칠 뿐이므로 세번째 추가행은 필요하지 않음

정렬하여 중복을 제거하는 작업이 제외되면서 불필요한 리소스 낭비를 방지

 

* 참고

- 업무에 바로쓰는 SQL 튜닝(도서) - 4장 악성 SQL 튜닝으로 초보자 탈출하기

댓글