어떤 컬럼에 인덱스를 걸어야 할까?
WHERE 문이 사용된 SQL 튜닝하기 에서 WHERE 문에 사용된 컬럼에 인덱스를 걸면 좋다고 했다
하지만 자주 사용되고 WHERE 절이 사용된 쿼리를 튜닝할 때 어떤 컬럼에 인덱스를 거는 것이 효율적일지 판단해야 한다. 이를 위해서 먼저 하나씩 테스트를 해보며 실행 계획을 확인해 볼 수 있다.
MariaDB 예제
-- 테이블 생성
CREATE TABLE users(
id INT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100),
department VARCHAR(100),
created_at TIMESTAMP DEFAULT current_timestamp
);
-- 가짜 데이터 100만개 생성
INSERT INTO users(NAME, department, created_at)
WITH RECURSIVE cte(n) AS (
SELECT 1 AS n UNION ALL SELECT n+1 from cte WHERE n < 1000000
)
SELECT CONCAT('User', LPAD(cte.n, 7, '0')) AS NAME,
case
when n%10=1 then 'engineering'
when n%10=2 then 'marketing'
when n%10=3 then 'sales'
when n%10=4 then 'finance'
when n%10=5 then 'hr'
when n%10=6 then 'it'
when n%10=7 then 'cs'
when n%10=8 then 'rnd'
when n%10=9 then 'operations'
ELSE 'pm'
END AS department,
TIMESTAMP(DATE_SUB(NOW(), INTERVAL FLOOR(RAND()*3650) DAY) + INTERVAL FLOOR(RAND()*86400) SECOND) AS created_at -- 최근 10년 내에 생성된 날짜 랜덤
FROM cte;
다음의 쿼리를 튜닝해본다고 하자.
SELECT * FROM users WHERE department = 'sales' and created_at >= DATE_SUB(NOW(), INTERVAL 3 DAY);
① created_at 컬럼에 인덱스 설정
users 테이블에 아무런 인덱스가 설정되어 있지 않았을 때 (PK 제외) 먼저 created_at 컬럼에 인덱스를 설정하면 보통 0.016초가 걸리고 type: range 스캔을 한다.
② department 컬럼에 인덱스 설정
users 테이블에 아무런 인덱스가 설정되어 있지 않았을 때 (PK 제외) department 컬럼에 인덱스를 설정하면 보통 1.xxx초가 걸리고 type: ALL 이 나온다. (MySQL에서는 department가 비고유 값이기 때문에 ref가 나올 수 있음)
③ created_at, department 각각 따로 인덱스 설정
created_at, department 컬럼 모두 각각 인덱스를 설정했을 경우(멀티 인덱스 x) 실행 계획 결과 실제로 사용한 인덱스 키는 created_at 만 사용하였다. 따라서 두 컬럼 모두 인덱스를 설정할 필요가 없었다
→ created_at만 인덱스 설정하는 것이 효율적
④ created_at, department 멀티 컬럼 인덱스 설정
두 컬럼을 순서와 상관없이 멀티 컬럼 인덱스를 설정했을 때 보통 0.000~0.015초가 걸리고 type: range가 나온다. 멀티 컬럼 인덱스 설정의 컬럼 순서와 상관없이 created_at만 걸었을 때와 차이가 거의 없음
→ created_at만 인덱스 설정하는 것이 효율적
어떤 컬럼에 인덱스를 거는 것이 효율적일지, 몇개의 인덱스를 설정하는 것이 좋을지 정답은 없다.
직접 실행해보고 실행 계획을 분석해보며 최적의 답을 찾아가는 것이 중요하다.
★ 단일 컬럼에 설정하는 인덱스를 설정했을 때와 멀티 컬럼 인덱스를 설정했을 때의 성능 차이가 별로 나지 않는다면, 멀티 컬럼 인덱스를 사용하지 말고 일반 인덱스를 활용하는 것이 좋다.
'Backend 개발 > SQL 성능 개선' 카테고리의 다른 글
ORDER BY 문이 사용된 쿼리 튜닝 방법 (3) | 2025.05.01 |
---|---|
인덱스가 동작하지 않는 경우 (0) | 2025.04.30 |
WHERE 문이 사용된 SQL 튜닝하기 (0) | 2025.04.28 |
한번에 너무 많은 데이터를 조회하는 SQL문 튜닝 방법 (0) | 2025.04.24 |
실행 계획 컬럼, type 의미 (0) | 2025.04.23 |