1시간. 사기 탐지 시스템이 비정상 거래를 포착하고 대응하기까지 걸리는 시간이다. 머신러닝 모델을 새로 학습시키고 배포하는 데 며칠씩 걸리던 과거와 달리, 이제는 SQL 패턴 하나로 즉각적인 이상 징후를 잡아낼 수 있다. 마치 둑이 터지기 전 미세한 균열을 찾아내는 것과 같다. 그런데 이 과정은 거창한 인공지능보다 데이터베이스 내의 단순한 조인과 윈도 함수(Window Function, 특정 범위의 데이터를 계산하는 함수)에서 시작된다.
거래 데이터에서 사기 징후를 찾는 SQL 패턴
사기 탐지는 신용카드, 전자상거래, 정부 지원금 등 돈이 흐르는 모든 곳에서 필수적이다. 실무에서는 보통 속도, 불가능한 이동, 금액 이상, 가맹점 집중, 비정상 시간대, 윈도 함수 기반 신호 순으로 패턴을 쌓아 올린다. 가장 먼저 적용할 것은 속도(Velocity) 패턴이다. 이는 짧은 시간 안에 같은 카드 소유자의 거래가 몰리는 구간을 찾는 방식이다. 최근 30일 거래를 시간 단위로 묶고, cardholder_id(카드 소유자 식별자)별 거래 수가 임계값을 넘는지 확인한다. 1분, 5분, 1시간 단위로 병렬 분석하면 카드 테스트 조직의 초단기 공격과 혜택 부정 수급자의 장기적 움직임을 모두 포착할 수 있다.
물리적 이동과 금액 패턴의 비교
예전에는 단순히 거래 횟수만 세었다면, 이제는 물리적 이동 거리까지 계산한다. 불가능한 이동(Impossible travel) 패턴은 LAG() 함수로 직전 거래의 시간과 위치를 가져와 현재 위치와 비교한다. 예를 들어, 시카고에서 결제된 지 7분 만에 로스앤젤레스에서 결제가 발생했다면 이는 복제 카드일 확률이 매우 높다. 대권 거리(Great-circle distance, 지구 표면의 두 지점 사이 최단 거리)를 계산하는 haversine(하버사인) 함수를 활용하면 상업용 제트기 속도인 600mph를 기준으로 비정상 거래를 즉시 걸러낼 수 있다. 금액 이상(Amount anomalies) 패턴 또한 유용하다. $1.00이나 $499.99처럼 카드 테스트나 한도 회피를 시사하는 특정 금액대를 필터링하는 방식이다. 이는 혜택 거래에는 잘 맞지 않지만, 카드 번호 유효성을 검증하려는 공격자를 찾아내는 데 효과적이다.
가맹점 집중과 시간대 분석의 결과
개발자가 바로 체감하는 변화는 윈도 함수를 활용한 신호 조합이다. 단순히 개별 규칙을 적용하는 대신, 거래별로 직전 거래 이후 경과 시간, 가맹점 변경 여부, 최근 24시간 누적 금액 등을 파생 컬럼으로 생성해 둔다. 이렇게 물리화된 컬럼은 사기 규칙을 단순한 필터 표현식으로 변환해 준다. 결과적으로 새로운 사기 가설을 엔지니어링 티켓으로 발행하지 않고도 SQL 필터만으로 몇 시간 안에 대응할 수 있게 된다. 가맹점 단위의 이상 집중이나 평소 사용 시간대 밖의 거래까지 점수화하여 여러 신호에 동시에 걸리는 거래를 우선 검토하면, 오탐(False Positive)을 줄이면서도 실제 사기를 놓치지 않는 정교한 방어 체계를 구축할 수 있다.
실무적 주의사항과 최적화
데이터 웨어하우스의 성능을 고려할 때, 윈도 함수는 비용이 많이 드는 작업이다. 전체 데이터셋에 무작정 함수를 적용하기보다, 날짜 범위를 먼저 필터링한 뒤 필요한 파티션에만 적용해야 예산을 절감할 수 있다. 또한, 레거시 시스템의 NULL 값이나 센티널 값(특정 의미를 가진 예외 데이터) 처리에 유의해야 한다. 모든 규칙은 완벽하지 않으므로, 단일 규칙으로 자동 차단하기보다는 여러 신호를 종합해 점수화하고, 최종적으로 사람의 검토가 필요한 플래그를 생성하는 피드백 루프를 구성하는 것이 가장 안전하다.
사기 탐지의 핵심은 복잡한 알고리즘이 아니라, 데이터의 흐름 속에 숨겨진 비정상적인 패턴을 얼마나 빠르게 SQL로 정의하고 검증하느냐에 달려 있다.



