SQL 안티패턴

5 hours ago 1

  • 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 코딩은 생산 코드처럼 공유/버전 관리/리뷰/최적화하는 습관에서 출발함
  • 초기 설계에 몇 분 투자해, 명확성과 일관성을 고민하면 향후 재작업과 혼란이 크게 줄어듦

Read Entire Article