---
title: "ORM이 결국 알려준 것: 그냥 SQL을 배우는 게 낫다"
published: 2026-07-01T04:14:01.000Z
canonical: https://jeff.news/article/4677
---
# ORM이 결국 알려준 것: 그냥 SQL을 배우는 게 낫다

ORM은 단순한 CRUD에서는 편하지만, 테이블이 넓어지고 조인이 많아지는 순간 추상화 비용이 확 튄다는 글이다. 저자는 Hibernate 같은 ORM을 쓰면서 SELECT *급 쿼리, 과한 객체 변환, 트랜잭션 경계, 마이그레이션 문제를 겪고 결국 쿼리를 데이터베이스 API처럼 보는 쪽으로 생각이 바뀌었다고 말한다.

- ORM이 제일 위험해지는 순간은 테이블이 슬슬 살찌기 시작할 때임
  - 처음에는 속성 5개짜리 Foo 엔티티라서 `query(Foo.class)`가 별문제 없어 보임
  - 그런데 클라이언트 데이터가 계속 붙고, 보고서용 비즈니스 로직 때문에 컬럼이 100개까지 늘어나면 이 코드는 사실상 `SELECT *`가 됨
  - 저자는 실제로 projection을 추가해서 분 단위로 걸리던 쿼리를 초 단위로 줄였다고 함. 병목은 DB가 아니라 DB row를 Java 객체로 바꾸는 작업이었음

- 외래 키도 ORM에서는 생각보다 세게 터짐
  - 클래스 간 링크를 외래 키로 표현하고, 설정을 조심하지 않으면 객체 하나 가져오려고 조인이 줄줄이 붙음
  - 저자가 본 사례 중 하나는 단일 객체 접근에 600개 넘는 속성과 14개 조인이 따라붙었음. 와, 이건 객체 하나가 아니라 이삿짐임

- 결론은 꽤 단순함. ORM을 잘 쓰려면 SQL을 알아야 함
  - 효율이 중요해지는 순간 ORM이 생성하는 SQL을 이해해야 하고, 어떻게 하면 원하는 SQL을 뽑게 할지 역으로 설득해야 함
  - 이럴 거면 그냥 SQL을 쓰는 편이 낫다는 게 저자의 주장임. SQL을 모르는 척하려고 ORM DSL을 배우는 게 더 이상한 그림이라는 것

- 복잡한 쿼리는 데이터베이스가 더 잘하는데, ORM은 그걸 앱 코드로 끌고 오게 만들 때가 많음
  - 윈도 함수(window function) 같은 SQL 기능은 ORM으로 쓰기 고통스러운 편임
  - 그래서 쿼리를 단순하게 유지하려다 보면 DB에서 빠르게 끝낼 일을 앱으로 대량 전송해서 처리하게 됨
  - 저자는 결국 테이블 표현은 ORM에서 얻고, 쿼리는 템플릿 기반 SQL로 직접 작성하는 절충안을 택함

- 데이터 정의를 어디에 둘지도 피할 수 없는 중복 문제임
  - 데이터베이스와 애플리케이션 양쪽에 모델 정의가 생김
  - 정의를 앱에만 두면 ORM 코드로 DDL을 써야 하고, 정의를 DB에만 두면 앱에서 문자열 타이핑을 피하기 위한 표현이 또 필요함
  - 저자는 데이터 정의의 원본은 데이터베이스에 두고, 앱에는 편의용 표현을 두는 쪽을 선호함

- 마이그레이션은 ORM이 별로 도와주지 못하는 영역이라고 봄
  - 앱 모델 바꾸는 건 쉽지만, 데이터베이스는 영속 상태라 스키마 변경이 훨씬 까다로움
  - ORM은 객체 상태 저장에는 관심이 많지만 실제 데이터 마이그레이션 문제를 해결해주지는 않음
  - 그래서 저자는 객체가 아니라 쿼리를 데이터베이스 API로 보고, 반환 타입이 있는 함수처럼 생각하는 쪽으로 갔다고 함

- 트랜잭션과 identity 문제도 추상화가 새는 정도가 아니라 그냥 넘침
  - 앱에서는 객체 identity가 메모리 위치 같은 의미를 갖지만, DB에서는 식별자가 영속 상태의 일부임
  - ORM을 쓰다 보면 실제 DB id를 얻으려고 cache flush나 partial commit 같은 조작을 해야 할 때가 있음
  - 트랜잭션 경계도 언제 시작되고 끝나는지 계속 신경 써야 해서, 특정 컨텍스트에서만 동작하는 함수가 생기기 쉬움

> [!IMPORTANT]
> 이 글의 핵심은 "ORM 쓰지 마라"보다 "ORM이 SQL 학습을 대체해주지 않는다"에 가까움. RDBMS를 쓴다면 SQL은 결국 피할 수 없는 운영 지식임

---

## 기술 맥락

- 이 글에서 말하는 선택은 ORM을 완전히 버리자는 게 아니라, 쿼리 작성 책임을 어디에 둘지 다시 정하자는 쪽이에요. 객체 모델은 앱에서 편하지만, 실행 계획과 데이터 이동량은 결국 SQL과 데이터베이스가 결정하거든요.

- 저자가 SQL을 선호하는 이유는 성능 문제가 생겼을 때 관찰 가능한 대상이 명확하기 때문이에요. ORM DSL을 고치면서 어떤 SQL이 나올지 추측하는 것보다, 처음부터 projection과 join을 직접 통제하는 편이 디버깅 경로가 짧아요.

- 트레이드오프도 있어요. ORM은 타입이 있는 테이블 표현, 반복 CRUD, 관계 탐색을 편하게 해주지만, 복잡한 리포팅 쿼리나 윈도 함수, 대량 데이터 처리에서는 SQL의 표현력을 따라가기 어렵다는 거예요.

- 실무적으로는 모든 쿼리를 한 방식으로 통일하려고 하기보다, 단순한 쓰기와 조회는 ORM에 맡기고 병목이 되는 읽기 경로는 SQL을 직접 쓰는 식의 혼합 전략이 더 현실적이에요. 저자가 말한 "쿼리가 DB의 API"라는 관점도 이 지점에서 나와요.

## 핵심 포인트

- ORM은 넓은 테이블에서 불필요한 컬럼과 조인을 끌고 와 성능 문제를 만들기 쉽다
- 효율적인 쿼리를 쓰려면 결국 SQL을 알아야 하고, 그러면 ORM 쿼리 DSL을 우회하고 싶어진다
- 데이터 정의와 마이그레이션은 애플리케이션 객체 모델보다 데이터베이스 중심으로 다루는 편이 낫다는 주장이다

## 인사이트

2014년 글인데도 지금 백엔드 개발자한테 꽤 잘 꽂힌다. ORM을 버리자는 선언이라기보다, ORM이 SQL을 모르게 해주는 도구라는 환상을 버리라는 쪽에 가깝다.
