프로그래밍SQL 개발자

SQL에서 커서를 사용한 시리얼 데이터 처리의 특징, 장점과 단점을 설명하십시오. 커서를 사용할 때와 집합 기반(set-based) 작업을 선호해야 할 때는 언제인지에 대해 설명하십시오. 커서 사용 예제를 제시하십시오.

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

답변.

커서는 SQL에서 데이터 집합을 행 단위로 순회하고 각 레코드에 대해 특정 작업을 수행할 수 있도록 해줍니다. 이는 프로그래밍에서의 반복과 유사합니다. SQL 단일 쿼리로는 불가능한 복잡한 단계별 로직에 유용합니다(예: 외부 상태 변경이 포함된 단계적 계산).

커서 예제:

DECLARE my_cursor CURSOR FOR SELECT id, balance FROM Accounts WHERE isActive = 1; OPEN my_cursor; DECLARE @id INT, @bal DECIMAL(10,2); FETCH NEXT FROM my_cursor INTO @id, @bal; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE Accounts SET balance = @bal * 1.05 WHERE id = @id; FETCH NEXT FROM my_cursor INTO @id, @bal; END CLOSE my_cursor; DEALLOCATE my_cursor;

장점:

  • 각 행이 개별 처리 또는 외부 조건 확인이 필요한 복잡한 프로시저를 구현할 수 있습니다.
  • 오래된 시스템과 통합하거나 마이그레이션 시 단계별 제어가 필요할 때 이상적입니다.

단점과 함정:

  • 커서는 일반적으로 매우 느립니다: 처리가 행 단위로 이루어지기 때문입니다;
  • 많은 리소스를 소모하고 테이블을 잠글 수 있습니다;
  • 대량 데이터에 대해 확장성이 떨어집니다;
  • 집합 기반 SQL로 다시 작성하거나 배치 처리를 사용하는 것이 좋습니다.

트릭 질문.

트리거 내부에서 커서를 사용할 수 있습니까? 이것이 데이터베이스 성능에 어떤 영향을 미칠 수 있습니까?

답변 및 예제: 트리거 내부에서 커서를 사용하는 것은 가능하지만 매우 권장되지 않습니다 — 각 DML 연산이 영향을 받는 각 행에 대해 커서를 실행할 수 있어 요청과 잠금이 폭발적으로 증가할 수 있습니다.

CREATE TRIGGER UpdateBalance ON Accounts AFTER INSERT AS DECLARE c CURSOR FOR SELECT id FROM inserted; -- 나쁨! OPEN c; -- ...

사례

프로젝트: 소매 주문 요약. 재고에서 결함이 발견되면 재고를 계산해야 하는 작업이 있었습니다 — 다음 배치는 수동으로 할인 업데이트를 통해 재계산이 필요합니다. 배치를 순회하는 데 커서를 사용했습니다. 나중에 여러 번 실행했을 때 스레드가 몇 시간 동안 잠겼고 서버의 부하가 기하급수적으로 증가했으며, 잠금 경합이 실패로 이어졌습니다.


사례

프로젝트: ERP, 데이터 마이그레이션. 수입 처리 절차에 커서를 통한 오류 처리를 추가했습니다. 500만 행에서 커서가 집합 기반 UPDATE + CASE를 사용한 유사한 배치 처리보다 40배 느리다는 것을 고려하지 않았습니다. 느린 마이그레이션으로 마감일이 미뤄졌습니다.


사례

프로젝트: 금융 회사의 청구. 자금 이동 테이블 업데이트에 새로운 집계 잔액을 계산하기 위해 커서를 추가했습니다. 프로덕션에서 "STOP THE WORLD"가 발생하여 한 행의 삽입조차도 많은 행에 대해 중첩 커서를 실행해야 했기 때문에 서비스 작업이 지연되었습니다.