프로그래밍SQL 개발자

SQL에서 조건부 데이터 필터링 로직을 효율적으로 구현하는 방법은 무엇인지? (예: 조건이 동적으로 설정된 웹 필터)

Hintsage AI 어시스턴트로 면접 통과

답변.

SQL에서 동적 필터링은 자주 요구됩니다. 예를 들어, 사용자에 의해 설정된 필터가 있는 보고서나 검색의 경우. 주요 접근법:

  1. 동적 SQL — 쿼리 문자열은 빈 값이 아닌 매개변수에 대해서만 조건을 포함하여 런타임에 생성됩니다. 유연하지만, SQL 인젝션에 대한 보호를 신경 써야 합니다(매개변수/이스케이프 사용).
  2. OR를 통한 조건부 필터링 — 조건이 설정되지 않은 경우 결과에 영향을 주지 않도록 (@param IS NULL OR 필드 = @param)과 같은 구조를 사용합니다. 이 방법은 안전하지만 때때로 인덱스의 비효율적인 사용을 초래할 수 있습니다.

주문 검색을 위한 템플릿 예시:

SELECT * FROM Orders WHERE (@CustomerID IS NULL OR CustomerID = @CustomerID) AND (@Status IS NULL OR Status = @Status) AND (@DateFrom IS NULL OR OrderDate >= @DateFrom) AND (@DateTo IS NULL OR OrderDate <= @DateTo);

함정 질문.

질문: (@param IS NULL OR Column = @param) 접근법 사용 시 성능이 악화되는 이유는 무엇인가요? — Column에 인덱스가 존재할 경우에도?

답변: 이 템플릿은 최적화자가 인덱스를 효율적으로 사용할 수 없게 만듭니다. 조건에 변수가 포함되어 쿼리가 인덱스 검색 대신 전체 테이블 스캔으로 변환됩니다. 대량의 데이터에서는 치명적입니다.

예시:

WHERE (@name IS NULL OR name = @name)

이 조건은 단순히 name = @name과 동일하지 않으며, 데이터베이스가 쉽게 인덱스를 사용할 수 없게 만듭니다.


이야기

클라이언트 데이터베이스 검색 서비스에서 (@par IS NULL OR Field = @par)를 통한 "유연한 필터"를 도입했으며, 주문량이 증가함에 따라 검색 속도가 초 단위에서 분 단위로 떨어졌습니다 — 최적화자가 특정 값을 결정할 수 없었기 때문에 인덱스가 제대로 작동하지 않았습니다.


이야기

e-commerce 프로젝트에서는 매개변수 없이 동적 SQL을 통해 필터링을 설정하고 값을 직접 대입했습니다. 인젝션으로 인해 사용자들이 모든 고객의 목록을 볼 수 있게 되며 필터가 취약했습니다 — 비밀번호를 긴급히 변경해야 했습니다.


이야기

BI 보고서는 인덱스 스캔을 방해하는 OR 조건을 고려하지 않고 매개변수화된 템플릿으로 작성되었습니다. 백만 개의 데이터 집합에 대해 보고가 "멈추게" 되었고, 최적의 조건과 다양한 매개변수 조합에 대한 별도의 논리를 사용하는 필터링으로 다시 작성될 때까지 이 상태가 지속되었습니다.