[프로그래머스 SQL] 비트 연산 조인과 1:N 데이터 증식 방어 (JOIN vs EXISTS)

이성진·2026년 3월 28일

프로그래머스 SQL

목록 보기
5/7

SQL 문제 해결 회고
프로그래머스 '조건에 맞는 개발자 찾기' 문제를 풀며, 일반적인 외래키(FK) 매핑이 아닌 비트 연산(Bitwise Operation)을 통한 조인 기법을 학습했다. 더 나아가, JOIN 연산 시 필연적으로 발생하는 '1:N 데이터 증식(뻥튀기)' 문제를 해결하기 위해 DISTINCT를 사용한 사후 처리 방식과 EXISTS를 사용한 사전 차단 방식의 아키텍처 차이를 깊이 있게 분석해 본다.

📌 1. 문제의 핵심: 비트 마스킹(Bit Masking) 해독

하나의 정수(SKILL_CODE) 안에 여러 개의 스킬 상태를 구겨 넣는 비트 마스킹 방식에서는 일반적인 등호(=)로 조인할 수 없다. 일치 여부가 아니라 '교집합'을 구해야 하므로, 비트 단위 연산자 & (AND)를 사용해야 한다.

  • 조인 조건: (D.SKILL_CODE & S.CODE) = S.CODE
  • 개발자의 스킬 코드와 특정 스킬 코드를 & 연산했을 때, 원본 스킬 코드가 그대로 나온다면 해당 스킬을 보유하고 있다는 뜻이다.

🚨 2. 첫 번째 접근: JOIN + DISTINCT (사후 처리)

가장 직관적인 방법은 비트 연산을 조건으로 JOIN을 수행하는 것이다.

SELECT DISTINCT D.ID, D.EMAIL, D.FIRST_NAME, D.LAST_NAME
FROM DEVELOPERS AS D
JOIN SKILLCODES AS S ON (D.SKILL_CODE & S.CODE) = S.CODE
WHERE S.NAME IN ('Python', 'C#')
ORDER BY D.ID ASC;

딜레마: 왜 DISTINCT가 필수적인가?

조인을 수행하는 순간, 압축되어 있던 코드가 풀리며 개발자 1명의 데이터가 자신이 보유한 스킬 개수만큼 여러 줄로 복제(증식)된다. 만약 어떤 개발자가 Python과 C#을 모두 할 줄 안다면, 조인된 거대한 임시 테이블에는 그 개발자의 행이 2줄 생성된다. 이 상태로 SELECT를 하면 동일한 개발자가 두 번 출력되는 논리적 오류가 발생하므로, 마지막에 DISTINCT로 중복을 제거해 주어야만 정답이 된다.

하지만 데이터가 수천만 건이라면? 쓸데없이 데이터를 1:N으로 복제해 놓고 다시 압축하는 것은 심각한 메모리 낭비를 초래한다.

🛡️ 3. 최적화된 아키텍처: EXISTS (원천 봉쇄)

JOIN이 두 테이블을 물리적으로 '결합'하여 데이터를 증식시킨다면, EXISTS는 결합하지 않고 서브쿼리를 통해 '존재 여부'만 질문하는 방식이다.

SELECT D.ID, D.EMAIL, D.FIRST_NAME, D.LAST_NAME
FROM DEVELOPERS AS D
WHERE EXISTS (
    SELECT 1 
    FROM SKILLCODES AS S
    WHERE S.NAME IN ('Python', 'C#')
      AND (D.SKILL_CODE & S.CODE) = S.CODE
)
ORDER BY D.ID ASC;

왜 이 방식이 압도적으로 우수한가? (성능 최적화)

  1. 쇼트 서킷 평가 (Short-Circuit Evaluation): EXISTS는 서브쿼리 내에서 조건에 맞는 데이터(예: Python)를 딱 하나라도 발견하는 순간, 그 뒤의 데이터(예: C# 보유 여부)는 더 이상 쳐다보지도 않고 탐색을 즉시 종료(True 반환)한다. 불필요한 연산을 칼같이 끊어버린다.
  2. 데이터 원형 보존 (무결성): DEVELOPERS 테이블의 데이터가 다른 테이블과 결합하지 않으므로, 원본 데이터가 단 한 줄도 복제되지 않는다. 애초에 중복이 발생하지 않으므로 무거운 DISTINCT 연산을 수행할 필요가 전혀 없다.

💡 결론 및 SQL SOP 업데이트

원칙: 대상 테이블(A)의 컬럼만 출력해야 하는데, 조건 확인을 위해 1:N 관계인 참조 테이블(B)을 뒤져야 한다면, 무지성 JOIN + DISTINCT를 쓰기 전에 EXISTS 서브쿼리로 탐색 공간을 소거할 수 있는지 먼저 검토하라.

profile
알고리즘과 cs지식 학습

0개의 댓글