본문 바로가기
SQL 튜닝/인덱스 조정

[SQL 튜닝] 인덱스 없이 작은 규모의 데이터를 조회하는 나쁜 SQL 문

by Johnny's 2023. 7. 30.

인덱스 없이 작은 규모의 데이터를 조회하는 나쁜 SQL 문

현황 분석

튜닝 전 실행 계획 |

이름이 Georgi이고, 성이 Wielonsky인 사원 정보를 출력하는 쿼리

EXPLAIN
SELECT *
	FROM 사원
	WHERE 이름 = 'Georgi' AND 성 = 'Wielonsky';

- SQL문 결과 : 총 1건의 결과 출력, 85.8ms 소요

- 사원 테이블 : 테이블 풀 스캔(type항목 : ALL) 

- 스토리지 엔진에서 가져온 전체 데이터 중 WHERE 이름 = 'Georgi' AND 성 = 'Wielonsky' 조건절로 필요한 데이터 추출(Extra 항목: Using where)하여 출력

 

튜닝 수행

- 최종적으로 1건의 데이터를 가져오고자 테이블을 처음부터 끝까지 풀 스캔하는 방식은 비효율

- 조건절에 해당하는 열들이 자주 호출된다면, 인덱스로 빠른 데이터 접근을 유도하는 방식으로 튜닝의 방향을 잡을 수 있음

- 이름 열과 성 열을 대상으로 인덱스를 생성하기 전에 먼저 더 다양한(많은) 값이 있는 열이 무엇인지 파악

- 이름 열 : 1,275개, 성 열 : 1,637개 데이터 범위를 더 축소할 수 있는 성 열을 선두 열로 삼아 인덱스 생성

SELECT COUNT(DISTINCT(이름)) 이름_개수,
	COUNT(DISTINCT(성)) 성_개수,
	COUNT(1) 전체
FROm 사원;

- I_사원_성_이름 인덱스 생성 : '성 + 이름' 순

ALTER TABLE 사원
	ADD INDEX I_사원_성_이름 (성, 이름);
SHOW INDEX FROM 사원;

 

튜닝 결과

튜닝 후 실행 계획 |

인덱스 생성한 뒤 SQL문 수행 (튜닝 전과 동일)

EXPLAIN
SELECT 매핑.부서번호
	FROM (SELECT DISTINCT 부서번호
			FROM 부서사원_매핑 매핑
			) 매핑
WHERE EXISTS (SELECT 1
				FROM 부서관리자 관리자
					WHERE 부서번호 = 매핑.부서번호)
ORDER BY 매핑.부서번호;

- 85.8m→ 0.4ms (시간 단축)

- 사원 테이블에서 I_사원_성_이름 인덱스로 인덱스 스캔 수행

- 스토리지 엔진에서 성 열과 이름 열에 조건절을 써서 데이터에 접근하므로 1건의 데이터만 최종 반환

 

* 참고

- 업무에 바로쓰는 SQL 튜닝(도서) - 5장 악성 SQL 튜닝으로 전문가 되기

댓글