반응형
✅ 쿼리 튜닝이란?
- 느린 쿼리를 빠르게 만드는 작업
- 데이터를 빠르게 가져오기 위해 인덱스, 쿼리 구조, 실행 계획을 최적화하는 것
📌 1. 인덱스 (INDEX) — 가장 중요!
🔹 인덱스란?
- 책의 목차처럼, 찾고자 하는 데이터를 빠르게 찾게 해주는 구조
- 테이블이 커질수록 인덱스 없이는 쿼리 성능이 급격히 떨어짐
🔹 인덱스 확인
-- 테이블에 설정된 인덱스 조회
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('dbo.YourTableName');
🔹 인덱스 생성
CREATE NONCLUSTERED INDEX idx_User_Status ON dbo.Users (Status);
⚠️ 너무 많은 인덱스를 만들면 쓰기 성능이 느려지고, 관리 복잡도가 증가하니 꼭 필요한 컬럼만 인덱싱!
📌 2. SELECT 최소화
- SELECT * ❌ → 꼭 필요한 컬럼만 선택
-- 비효율적
SELECT * FROM Users;
-- 효율적
SELECT UserID, UserName FROM Users;
📌 3. WHERE 조건 최적화
- 인덱스를 잘 타게 하려면 WHERE 절도 최적화 필요
❌ 인덱스를 못 타는 예
-- 함수 사용 (비추천)
WHERE YEAR(JoinDate) = 2024
✅ 인덱스를 타는 예
-- 범위 조건 사용
WHERE JoinDate >= '2024-01-01' AND JoinDate < '2025-01-01'
📌 4. JOIN 튜닝 (많이 느려지는 구간)
- 꼭 필요한 테이블만 JOIN
- JOIN 조건에 인덱스 있는 컬럼 사용
- 가능하면 INNER JOIN 사용 (OUTER JOIN은 더 느림)
SELECT u.UserName, o.OrderDate
FROM Users u
INNER JOIN Orders o ON u.UserID = o.UserID;
📌 5. 서브쿼리보단 JOIN 우선
-- 서브쿼리 (느릴 수 있음)
SELECT UserName FROM Users WHERE UserID IN (
SELECT UserID FROM Orders WHERE Total > 100
);
-- JOIN으로 변경
SELECT DISTINCT u.UserName
FROM Users u
JOIN Orders o ON u.UserID = o.UserID
WHERE o.Total > 100;
📌 6. 실행 계획 보기 (Execution Plan)
- 쿼리의 성능을 분석할 수 있는 가장 강력한 도구!
실행 계획 켜기
-- SSMS에서 직접 실행 전에 클릭: [실행 계획 보기 (Ctrl + M)]
실행 계획에서 볼 포인트
- Index Seek: 좋은 신호 ✅
- Index Scan / Table Scan: 느림 ❌
- Estimated Rows / Actual Rows: 차이 큰 쿼리는 튜닝 대상
📌 7. 통계 정보와 인덱스 유지 관리
MSSQL은 통계 정보를 바탕으로 실행 계획을 만드는데, 이게 오래되면 쿼리 성능이 떨어짐
통계 업데이트
UPDATE STATISTICS dbo.Users;
인덱스 재구성
ALTER INDEX ALL ON dbo.Users REBUILD;
📌 8. 파라미터화 쿼리 사용
- 쿼리 캐시(실행 계획 재사용)를 잘 활용하기 위해 변수/파라미터를 사용
DECLARE @Status NVARCHAR(10) = 'active';
SELECT * FROM Users WHERE Status = @Status;
📌 실전 예제 튜닝 전/후
👎 느린 쿼리
SELECT * FROM Orders WHERE YEAR(OrderDate) = 2024;
👍 튜닝된 쿼리
-- 인덱스를 타기 쉽게 수정
SELECT * FROM Orders WHERE OrderDate >= '2024-01-01' AND OrderDate < '2025-01-01';
✅ 마무리 요약표
항목 | 핵심 내 |
인덱스 | WHERE, JOIN, ORDER BY 등에 자주 쓰는 컬럼에 생성 |
SELECT | 꼭 필요한 컬럼만 선택 |
WHERE 조건 | 함수 사용 피하고 범위 조건 사용 |
JOIN | 꼭 필요한 테이블만, 인덱스 활용 |
실행 계획 | Table Scan → Index Seek로 바꾸는 게 목표 |
통계 / 인덱스 유지 | UPDATE STATISTICS / REBUILD INDEX |
캐시 활용 | 파라미터 쿼리로 실행 계획 재사용 |
✅ 5. 인덱스 관련 면접 질문 대비 요약
질문 | 답변 요약 |
Q1. 인덱스란? | 데이터를 빠르게 찾기 위한 자료 구조 (목차처럼 동작) |
Q2. 어떤 컬럼에 인덱스를 걸어야 하나요? | WHERE, JOIN, ORDER BY 자주 쓰이는 컬럼 |
Q3. 인덱스가 왜 항상 빠른가요? | 아니에요. 데이터양이 많을 때 빠르고, 작은 테이블은 오히려 느릴 수도 있음 |
Q4. 인덱스 단점은? | INSERT/UPDATE 시 성능 저하, 저장공간 사용 증가 |
Q5. 인덱스가 안 쓰이는 경우는? | - LIKE '%abc' - 함수 사용 (YEAR(date)) - 너무 많은 데이터 리턴할 때 |
Q6. 클러스터형 vs 비클러스터형 인덱스? | 클러스터형은 실제 데이터 정렬, 테이블당 1개만. 비클러스터형은 따로 저장 가능 |
Q7. 실행계획 어떻게 보나요? | SSMS에서 Ctrl + M 실행 또는 SET STATISTICS IO ON 사용 |
Q8. 인덱스 튜닝 경험 있나요? | (실습 예시처럼) 느린 쿼리를 Index Scan → Index Seek 되도록 튜닝한 경험 설명 |
'DB' 카테고리의 다른 글
[DataBase] 키(key) & 정규화란? (0) | 2024.11.20 |
---|---|
[DataBase] 인덱스와 넌인덱스 특징 & 차이 (0) | 2021.11.21 |
RDBMS와 NoSQL의 차이점 (0) | 2021.11.13 |