본문 바로가기
개발 공부/서버

[서버 성능 최적화] DB 쿼리 성능 최적화 전략, 인덱스, N+1 문제, 정규화/비정규화

by 악마의 개발자 2025. 5. 22.
반응형

서버 성능 최적화


💡 “API는 빠른데, DB가 느리면 의미가 없어요”

서버 응답 속도 문제의 주범은 의외로 많습니다.

“로직은 간단한데 결과가 늦게 와요.”
“SELECT 하나 날렸는데 2~3초 걸리네요…”

이럴 때 대부분 원인은 DB 쿼리 구조와 인덱스 설계입니다.


🔎 DB 쿼리 속도를 떨어뜨리는 3대 요인

문제 설명
❌ 인덱스 미사용 WHERE 조건에 맞는 인덱스가 없어 전체 탐색
❌ N+1 쿼리 반복적으로 DB에 여러 번 접근
❌ 과도한 JOIN 복잡한 테이블 관계로 인해 쿼리 지연 발생
 

🧱 1. 인덱스(Index) 최적화

인덱스는 책의 목차와 같아요.

원하는 데이터를 빨리 찾게 해주는 도우미!
하지만 너무 많으면 오히려 삽입·수정 속도 저하 발생 ⚠️

✅ 인덱스 기본 전략

  • 자주 검색하는 컬럼에 인덱스 생성 (ex. user_id, email)
  • WHERE, ORDER BY, JOIN ON 등에 자주 쓰이면 인덱스 고려
  • 복합 인덱스는 사용 순서 주의!
CREATE INDEX idx_user_email ON users(email);

✅ 인덱스 쓰면 SELECT가 1초 → 0.01초로 줄기도 해요!


🔁 2. N+1 문제

N+1 쿼리란?

→ 하나의 쿼리(N) 실행 후,
→ N개의 결과마다 추가 쿼리(+1)를 반복하는 비효율적인 구조

 

예시 (Node.js + ORM)

const posts = await Post.findAll();
for (const post of posts) {
  const user = await post.getUser(); // N번 호출
}

✅ 해결 방법: JOIN 또는 Include

const posts = await Post.findAll({
  include: [{ model: User }]
});

✅ DB에 한 번만 요청해서, 포스트 + 사용자 정보 한꺼번에 가져오기


🔄 3. 정규화 vs 비정규화

정규화

테이블을 나누고 관계로 관리
→ 데이터 중복 줄임, 구조적 → 성능 저하 가능성도 있음

비정규화

데이터를 중복해서라도 빠르게 읽기
→ 조회 속도 향상, INSERT/UPDATE는 불편해질 수 있음

비교 정규화 비정규화
장점 구조적, 무결성 ↑ 읽기 속도 빠름
단점 JOIN 많아져 느림 중복 데이터 많음
예시 user_id만 저장 user_name까지 같이 저장
 

읽기가 잦고 변경이 적은 데이터라면 비정규화도 고려!


🔧 쿼리 최적화 실무 팁

이유
SELECT * 지양 불필요한 데이터까지 조회
쿼리 실행 계획(EXPLAIN) 확인 인덱스 사용 여부 확인
슬로우 쿼리 로그 분석 오래 걸리는 쿼리 찾아서 개선
LIMIT, OFFSET 조절 페이징 성능 관리
캐싱 가능한 쿼리는 Redis 활용 인기 데이터 반복 조회 방지
 

🧠 정리 한마디!

DB 성능 최적화는 결국 “적게 읽고, 빠르게 찾고, 반복하지 않기”

 

✔️ 최적화 핵심 전략

  • 인덱스: 빠르게 찾아라
  • N+1 제거: 반복하지 마라
  • 정규화/비정규화: 상황에 따라 나누거나 합쳐라

 

반응형