-
SQL 안티패턴은 쿼리와 데이터 파이프라인의 유지보수를 어렵게 하고, 예상보다 느린 성능을 유발함
-
CASE WHEN 구문의 남용, 인덱스 컬럼에서 함수 사용, *SELECT * * 사용과 관련된 문제점 존재
-
DISTINCT로 단순히 중복 문제를 “해결”하려 하면, 근본적인 조인 오류를 숨기게 됨
-
View의 과도한 중첩과 깊은 서브쿼리 사용은 성능 저하와 디버깅 난이도 상승을 초래함
-
SQL을 생산 코드처럼 관리하고, 가독성을 고려한 초기 설계가 재작업을 줄여줌
소개
- 오늘은 SQL 안티패턴 중에서 자주 발생하며 영향력이 큰 몇 가지 사례를 중심으로 설명함
- 이러한 문제들은 데이터 신뢰 저하, 쿼리 개발 속도 저하 등 악순환을 유발함
- 아래 목록은 모든 사례를 포괄하지 않으며, 더 깊은 이해를 원한다면 Bill Karwin의 저서 추천함
과도하게 복잡한 CASE WHEN 구문
- 엔터프라이즈 환경에서 CASE WHEN 구문을 대규모로 사용해 상태 코드를 해석하는 경우가 많음
- 대시보드나 리포트의 빠른 개발을 위해 하나의 View에만 해당 CASE WHEN 로직을 추가하는 것은 장기적으로 안티패턴에 해당함
- 이는 중복 로직 복사/붙여넣기, 해석 불일치 문제를 유발하며 전체 쿼리 환경을 난잡하게 만듦
- 방지 방법으로 차원 테이블 또는 기준 뷰를 생성해 상태 코드 해석 로직을 일관되게 공유하는 것을 권장함
인덱스 컬럼에서 함수 사용
-
SQL Server 등에서 인덱스가 걸린 컬럼에 직접 함수를 사용하면, 인덱스가 제대로 활용되지 않음
- 예시: WHERE UPPER(name) = 'ABC'
- 이렇게 하면 데이터베이스가 전체 테이블 스캔을 수행할 수밖에 없으므로, 성능 저하 원인이 됨
- 인덱스를 제대로 활용하려면, 비교값을 미리 변환하거나 별도의 컬럼을 둘 필요가 있음
뷰에서 SELECT * 사용
- 뷰 개발 시 *SELECT * *를 사용하면 편해 보이지만, 구조(스키마)가 변경되면 뷰가 쉽게 깨질 수 있음
- 불필요한 컬럼까지 포함돼 의도치 않은 의존성 및 성능 문제가 발생함
DISTINCT 남용으로 중복 “해결”
-
SELECT DISTINCT를 단순히 사용해 중복을 제거하는 방식은, 잘못된 조인 조건이나 관계 정의 미흡에서 비롯된 근본 원인을 숨김
- 단기적으로는 결과가 맞아 보이지만, 추후 메트릭 산출 등에서 값 불일치 문제로 이어짐
- 올바른 방법은 조인 로직 보강을 통해 관계 정의 명확화가 선행되어야 함
뷰 계층의 과도한 중첩
- 여러 팀이 레이어링하여 View 위에 View를 계속 쌓다 보면, 의존성 복잡도가 급증함
- 이는 데이터베이스 성능 저하, 쿼리 간소화 및 디버깅 난이도 상승을 초래함
- 주기적으로 변환 계층을 정리해, 무거운 로직은 베이스 View나 Table에 물리화하는 것이 바람직함
과도한 깊이의 서브쿼리
-
서브쿼리는 초기 필터링에 유용하지만, 반복적으로 중첩됨에 따라 복잡성과 유지보수 난이도가 대폭 상승함
- 여러 단계로 중첩된 서브쿼리는 쿼리 디버깅을 어렵게 하고, 가독성을 해침
- 가능하면 CTE(Common Table Expression) 를 활용하여, 단계별 연산을 명확하고 읽기 쉽게 분리하는 것이 좋음
결론
-
SQL은 표면적으로 단순해 보이지만, 시스템이 커질수록 복잡성이 증대되는 특성 존재함
- 안티패턴은 속도, 마감, 임시방편 등에서 비롯되며, 시간이 쌓여 큰 문제로 발전함
- 효과적인 SQL 코딩은 생산 코드처럼 공유/버전 관리/리뷰/최적화하는 습관에서 출발함
- 초기 설계에 몇 분 투자해, 명확성과 일관성을 고민하면 향후 재작업과 혼란이 크게 줄어듦