ORM이 생성한 쿼리나 로그에서 복사한 SQL은 한 줄로 길게 이어져 있어 읽기 힘든 경우가 많습니다. 이 글에서는 SQL이 왜 지저분해지는지, 절 단위로 줄바꿈하면 무엇이 좋아지는지, 그리고 포맷팅이 실제로 버그를 잡는 데 어떻게 도움이 되는지 정리합니다.
왜 SQL은 한 줄로 뭉쳐서 나올까
직접 손으로 짠 SQL은 보통 절마다 줄바꿈을 해서 읽기 좋게 작성하지만, 실무에서 마주치는 SQL은 그렇지 않은 경우가 훨씬 많습니다. 대표적인 원인이 ORM(Object-Relational Mapping)입니다. Sequelize, TypeORM, Hibernate, Django ORM 같은 라이브러리는 코드에서 자동으로 SQL을 생성하는데, 사람이 읽기 좋게 만드는 것보다 실행에 필요한 최소한의 문자열을 만드는 데 최적화되어 있어 대개 한 줄로 출력됩니다. 두 번째는 로그와 모니터링 도구입니다. 슬로우 쿼리 로그, APM 대시보드, DB 프록시 로그 등은 저장 공간을 아끼고 파싱을 쉽게 하려고 개행 문자를 제거한 채로 쿼리를 기록합니다. 세 번째는 DB 관리 도구나 마이그레이션 파일을 export할 때 압축(minify)된 형태로 저장되는 경우입니다. 결과적으로 개발자는 SELECT·FROM·WHERE·JOIN·GROUP BY가 뒤섞인 100자가 넘는 한 줄짜리 문자열을 눈으로 해독해야 하는 상황에 자주 놓입니다.
절 단위로 나누면 구조가 보인다
SQL 포맷팅의 핵심은 쿼리를 절(clause) 단위로 나누어 각 절을 새 줄에 배치하는 것입니다. SELECT로 어떤 컬럼을 가져오는지, FROM으로 어느 테이블에서 가져오는지, WHERE로 어떤 조건을 거는지, JOIN으로 어떤 테이블을 어떻게 연결하는지, GROUP BY·ORDER BY로 어떻게 집계·정렬하는지가 각각 한 줄씩 분리되면 쿼리의 논리적 흐름이 눈에 들어옵니다. 한 줄로 뭉쳐 있을 때는 괄호 안에 괄호가 겹친 WHERE 조건이나, 여러 개의 JOIN이 어떤 순서로 어떤 컬럼을 기준으로 연결되는지 한눈에 파악하기 어렵지만, 절 단위로 줄바꿈하고 들여쓰기를 맞추면 각 요소가 독립된 블록으로 보여 구조 파악이 훨씬 쉬워집니다.
포맷팅으로 버그를 잡는 예시
가독성 개선은 단순히 보기 좋으라고 하는 작업이 아닙니다. 예를 들어 다음과 같이 한 줄로 이어진 쿼리가 있다고 해봅시다.
select o.id, u.name from orders o join users u on o.user_id = u.id where o.status = 'paid' and (o.amount > 100 or u.vip = 1) order by o.id
이 쿼리를 절 단위로 정렬하면 다음과 같이 펼쳐집니다.
SELECT o.id, u.nameFROM orders oJOIN users u ON o.user_id = u.idWHERE o.status = 'paid'AND (o.amount > 100 OR u.vip = 1)ORDER BY o.id
이렇게 펼쳐 놓으면 JOIN 조건이 정확한 컬럼끼리 연결되어 있는지, WHERE의 괄호가 의도한 대로 AND/OR 우선순위를 감싸고 있는지가 바로 보입니다. 한 줄로 뭉쳐 있을 때는 괄호 하나가 빠지거나 조건 순서가 바뀌어도 눈치채기 어렵지만, 절과 들여쓰기가 분리되면 이런 실수가 시각적으로 두드러집니다. 코드 리뷰 전이나 복잡한 쿼리를 디버깅할 때 직접 줄바꿈을 넣는 대신, 붙여넣기만 하면 SELECT·FROM·WHERE·JOIN 등 절 단위로 자동 정렬해 주는 도구를 쓰면 훨씬 빠릅니다.
🗃️ 이 작업, 도구로 바로 해보세요
지저분한 SQL 쿼리 포맷팅하는 방법 — 한 줄 SQL을 절 단위로 정렬하는 법