프로그래밍T-SQL 개발자 / ETL 엔지니어

T-SQL(Transact-SQL)에서 반복 및 분기 처리(루프, CASE, GOTO)를 효과적으로 구현하려면 어떻게 해야 합니까? 어떤 경우에 사용을 정당화할 수 있으며 성능에 대한 함정은 무엇입니까?

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

답변.

문제의 역사:
표준 SQL은 본래 반복(루프, 분기, 직접 이동) 요소가 없는 선언적 언어로 설계되었으나, T-SQL/PLSQL과 같은 확장을 통해 WHILE, CASE, 심지어 GOTO의 모방과 같은 구문이 가능해졌습니다.

문제:
반복 작업(레코드 처리 루프)은 대량 데이터를 처리할 때 성능 저하를 초래하는 경우가 많으며, 이를 "집합(세트) 기반" 접근 방식으로 대체하지 않는다면 성능 부진을 초래할 수 있습니다. 분기, CASE, IF는 매우 편리하지만 지나치게 중첩될 경우 코드의 가독성과 예측 가능성이 떨어집니다.

해결책:
제어 구조의 사용은 배치(bulk/set) 처리로 대체할 수 없는 경우에만 정당화되어야 합니다! 복잡한 계산의 경우에는 작은 루프, 트리거 또는 CASE를 사용하는 것이 허용됩니다. 대량 처리의 경우에는 윈도우 함수나 서브쿼리를 사용하는 UPDATE가 더 좋습니다.

코드 예시 (T-SQL):

DECLARE @i INT = 1 WHILE (@i <= 5) BEGIN IF @i % 2 = 0 PRINT CONCAT('짝수: ', @i) ELSE PRINT CONCAT('홀수: ', @i) SET @i = @i + 1 END

CASE 표현식:

SELECT num, CASE WHEN num % 2 = 0 THEN 'even' ELSE 'odd' END AS parity FROM numbers

주요 특징:

  • 루프와 분기의 사용은 순차적 처리를 위한 것으로, 수백만 개의 행에는 적용되지 않음
  • CASE 표현식은 행별 주석에 적합하나 집계/윈도우 함수의 대체물은 아님
  • 대부분의 작업에서 집합 기반(set-based) 접근 방식이 더 유리함: 한 번의 UPDATE 또는 INSERT

함정 질문.

CASE가 WHERE처럼 행 필터링에 사용될 수 있습니까?

아니요! CASE는 다른 값을 반환하지만 행을 필터링하지는 않습니다. CASE를 사용하여 필터링하려는 일반적인 실수가 발생하며 결과가 올바르지 않을 것입니다.

WHILE과 CURSOR는 어떤 차이가 있나요 — 동일한 건가요?

WHILE은 사용자 정의 변수 관리가 가능한 기본 루프입니다; CURSOR는 테이블의 레코드에 대해 작동하며, 행을 참조합니다. CURSOR는 자원 소모가 더 크며 대량 데이터에 대해 훨씬 느리게 작동하는 경우가 많습니다.

대량 처리에 대한 더 빠른 접근 방식은 WHILE 루프와 UPDATE인가, 하나의 집합 기반 UPDATE인가?

99%의 경우, 하나의 집합 기반 UPDATE(또는 INSERT)가 한 행씩 처리하는 루프보다 훨씬 빠릅니다(비교적 "유연해 보이더라도").

-- 잘못된 접근 DECLARE @id INT = 1 WHILE (@id <= 100000) BEGIN UPDATE t SET flag=1 WHERE id=@id SET @id = @id + 1 END -- 올바른 접근 UPDATE t SET flag=1 WHERE id BETWEEN 1 AND 100000

전형적인 오류 및 반패턴

  • 대량 작업에 대한 루프/WHILE의 과도한 사용
  • GOTO를 사용하여 중첩된 블록에서 탈출(프로그램 로직 손실)
  • CASE가 값을 변환하는 것이 아니라 필터링에 사용됨
  • 여러 개의 중첩된 IF를 통한 "터널링" 논리

실제 사례

부정적 케이스

백만 주문 상태를 업데이트하기 위해 각 id에 대해 UPDATE 루프를 작성했습니다. 처리 시간은 ~8시간이 걸렸습니다. 중간에 실패할 경우, 모든 작업이 손실되어 수동으로 수리해야 했습니다.

장점:

  • 소규모 데이터에서의 간단한 디버깅

단점:

  • 거대한 작업 시간
  • 확장성이 어렵습니다.
  • 실패 시 불일치 상태의 높은 확률

긍정적 케이스

집합 기반 UPDATE로 변경하여 단일 표현식으로 처리했습니다. 실행 시간이 6분으로 단축되었고, 처리 방식은 원자적입니다.

장점:

  • 훨씬 더 빠릅니다.
  • 전체 트랜잭션을 쉽게 제어할 수 있습니다.
  • 간단한 유지 관리

단점:

  • 각 행에 대해 개별적으로 "커스터마이징"하기 어려워지는 논리
  • 루프 코드에서만 이루어지는 "너무 유연한" 검사에 대한 제한이 발생합니다.