DB

쿼리 튜닝 방법 (핵심,기본적인 요소)

JUNGKEUNG 2025. 3. 23. 11:26
반응형

✅ 쿼리 튜닝이란?

  • 느린 쿼리를 빠르게 만드는 작업
  • 데이터를 빠르게 가져오기 위해 인덱스, 쿼리 구조, 실행 계획을 최적화하는 것

📌 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