개발일지

🔍 View, JOIN, IN절 비교 – 우리는 왜 ORM + IN절을 쓸까요?

makeviibe 2025. 7. 17. 14:46

안녕하세요 makeviibe 입니다.

서비스 개발을 하다 보면, 사용자 정보에 댓글 수를 붙이거나,

게시글과 작성자 정보를 한 번에 보여줘야 하는 등 복합 데이터를 조회해야 할 때가 많습니다.

이때 백엔드에서 DB에 쿼리를 날리는 방식은 보통 세 가지 중 하나입니다:

  1. View Table
  2. 즉석 JOIN 쿼리
  3. IN절 기반 다단계 조회

모두 목적은 같지만, 성능, 유지보수성, 확장성, 비용 측면에서는 차이가 큽니다.

makeviibe 팀은 다양한 실무 경험을 통해 ORM + IN절 조합이 가장 효과적이라고 판단하고 있으며,

그 이유를 아래에서 설명드리겠습니다.


✅ 1. View Table (뷰 테이블)

SQL 쿼리를 미리 정의해서 가상의 테이블로 만들어놓고,

그 뷰를 일반 테이블처럼 조회하는 방식입니다.

장점

  • 쿼리 재사용이 쉽고, 프론트/API 단에서 간단하게 조회 가능
  • 복잡한 조인을 SQL에서 미리 캡슐화 가능
  • 백엔드 코드가 단순해짐

단점

  • 성능 튜닝이 어려움 (인덱스 적용이 제한적)
  • 뷰가 변경되면 전체 영향을 추적하기 어려움
  • 읽기 전용이라 쓰기 연산에는 사용할 수 없음
  • ORM에서 다루기 까다로움 (Raw SQL 필요)

🛠 사용 예시


✅ 2. Join Query

실시간으로 SQL JOIN을 사용해서 여러 테이블을 묶어 조회하는 방식입니다.

장점

  • 즉시 필요한 데이터 조합 가능 → 유연한 쿼리 작성 가능
  • 정렬, 페이징, 필터링 등을 DB에서 바로 처리
  • 대부분 ORM에서 직접 지원되므로 익숙함

단점

  • JOIN이 많아질수록 복잡도와 부하 증가
  • N+1 문제 등 성능 이슈가 생기기 쉬움
  • 로직이 쿼리에 묻히면 유지보수가 어려움

🛠 사용 예시 (Spring JPA + Native Query)


✅ 3. IN절 기반 분리 조회

1차로 ID 목록을 조회하고, 2차로 IN절을 사용해 관련 데이터를 가져온 뒤

백엔드에서 조합하는 방식입니다.

장점

  • 쿼리가 단순하고 인덱스를 잘 활용함 → 속도 빠름
  • 서버에서 유연하게 가공 가능 → 병렬 처리, 캐싱 유리
  • ORM에서 다루기 쉬움 → 코드 구조 유지에 적합
  • 확장성 높고, 유지보수 용이

단점

  • 데이터 병합 로직을 직접 작성해야 함
  • IN 절에 너무 많은 ID가 들어가면 성능 이슈 발생 가능
  • 복잡한 정렬/페이징을 할 때 한계가 있을 수 있음

🛠 사용 예시


🛠 makeviibe 팀은 왜 ORM + IN절 조합을 쓰는가?

1. DB는 가볍게, 서버에서 나눠 처리하는 게 비용 효율적

  • 클라우드 DB는 CPU, I/O에 따라 과금
  • 반면 백엔드 서버는 수평 확장 용이 + 병렬 처리 가능
  • → 쿼리는 최대한 단순하게, 조합은 서버에서 → 운영비 절감

2. 유지보수가 훨씬 쉽다

  • 쿼리 복잡도는 코드에서 명시적으로 관리 가능
  • 조건 분기나 사용자 타입별 분리 로직 등을 서버에서 관리하기 쉬움
  • → 기능 추가 시 안전하고 빠르게 대응 가능

3. ORM과의 궁합이 가장 좋다

  • Kotlin/Spring 기준, JPA/QueryDSL에서
  • findByUserIdIn() 형태로 쉽게 활용 가능
  • 쿼리를 도메인 중심으로 나누고, 클린한 구조 유지에 최적

📊 정리: 상황별 쿼리 전략 비교


✍ 마무리하며

정답은 하나가 아닙니다.

상황, 트래픽, 데이터량, 유지보수 기준에 따라 전략이 달라져야 합니다.

makeviibe 팀은 기본적으로 다음의 원칙을 따릅니다:

  • DB는 단순하고 빠르게
  • 비즈니스 로직은 서버에서 명확하게
  • 운영비용과 확장성을 고려한 구조 선택

그래서 우리는 View나 복잡한 JOIN보다는

ORM + IN절 구조를 기본 전략으로 설계하고 있습니다.