핵심 인사이트 (3줄 요약)

  1. 본질: 드라이빙 테이블 (Driving Table)은 조인의 시작점이면서 이후 반복 횟수를 결정하는 집합이고, 드리븐 테이블 (Driven Table)은 그 반복마다 탐색되는 대상이다.
  2. 가치: 선택도 (Selectivity)가 높은 조건으로 드라이빙 집합을 먼저 줄이고, 드리븐 쪽에 적절한 인덱스나 접근 경로를 준비하면 중첩 루프 조인 (NL Join, Nested Loop Join)의 비용을 급격히 낮출 수 있다.
  3. 판단 포인트: 원본 테이블 크기보다 필터 후 기수성 (Cardinality), 조인 방식, 드리븐 접근 경로가 더 중요하며, FROM 절에 먼저 썼다고 자동으로 드라이빙이 되지는 않는다.

Ⅰ. 개요 및 필요성

드라이빙 테이블과 드리븐 테이블은 조인 실행 순서를 이해할 때 가장 먼저 잡아야 할 개념이다. 특히 중첩 루프 조인에서는 한쪽 집합을 먼저 읽고, 그 결과 각 행마다 다른 쪽을 반복 탐색한다. 이때 먼저 읽는 쪽이 드라이빙, 반복 탐색당하는 쪽이 드리븐이다.

이 구분이 중요한 이유는 조인 비용이 단순히 "두 테이블을 한 번씩 읽는 비용"이 아니기 때문이다. 드라이빙 집합이 10건이면 드리븐 탐색도 10번이면 끝나지만, 드라이빙 집합이 10만 건이면 같은 탐색이 10만 번 반복된다. 즉 조인의 체감 성능은 드라이빙 집합의 크기에 의해 크게 좌우된다.

아래 그림은 조인 비용이 왜 드라이빙 집합의 행 수에 민감한지를 압축해서 보여 준다. 핵심은 드리븐 비용이 한 번이 아니라 드라이빙 행 수만큼 곱해진다는 점이다.

┌────────────────────────────────────────────────────────────────────┐
│ Join cost is multiplied by outer rows                             │
├────────────────────────────────────────────────────────────────────┤
│ driving rows = 5      -> driven lookup repeated      5 times      │
│ driving rows = 500    -> driven lookup repeated    500 times      │
│ driving rows = 50,000 -> driven lookup repeated 50,000 times      │
│                                                                    │
│ rough cost ≒ access(driving) + rows(driving) x lookup(driven)      │
└────────────────────────────────────────────────────────────────────┘

따라서 드라이빙 테이블의 본질은 "먼저 읽는 테이블"이라는 문장으로 끝나지 않는다. 더 정확히는 조인 반복 횟수를 결정하는 제어 손잡이라고 이해해야 한다. 이 관점을 잡아야 옵티마이저 실행 계획을 읽을 때 왜 어떤 테이블이 먼저 잡혔는지 해석할 수 있다.

  • 📢 섹션 요약 비유: 드라이빙 테이블은 택배 기사에게 먼저 쥐여 주는 배송 목록과 같다. 목록이 5건이면 5번만 들르면 되지만, 목록이 5만 건이면 같은 도로도 끝없이 왕복하게 된다.

Ⅱ. 아키텍처 및 핵심 원리

드라이빙/드리븐 개념이 가장 선명하게 드러나는 곳은 중첩 루프 조인이다. 엔진은 보통 드라이빙 접근 → 조건 필터링 → 각 행마다 드리븐 접근 → 결과 결합 순서로 움직인다. 이때 드리븐 테이블은 반복 접근을 버텨야 하므로, 조인 키 인덱스나 매우 효율적인 접근 경로가 준비되어 있어야 한다.

역할엔진 입장 의미이상적인 조건잘못 잡았을 때 문제
드라이빙 테이블반복문의 바깥쪽 집합필터 후 결과 건수가 매우 적음반복 횟수 자체가 커짐
드리븐 테이블반복문 안쪽에서 매번 탐색되는 대상조인 키 인덱스, 빠른 랜덤 접근인덱스 없으면 반복 풀스캔 위험
조인 조건두 집합을 묶는 연결 키높은 선택도, 통계 정확성잘못된 기수 추정으로 순서 오판
옵티마이저 통계어느 쪽을 먼저 읽을지 판단하는 근거최신 통계 정보 유지잘못된 드라이빙 선택

아래 구조는 "작게 줄인 뒤 반복 접근한다"는 중첩 루프 조인의 핵심 원리를 보여 준다. 좋은 실행 계획은 드라이빙에서 이미 행 수를 최대한 줄여 놓고, 드리븐은 인덱스로 짧게 찌른다.

┌────────────────────────────────────────────────────────────────────┐
│ Nested Loop Join execution                                         │
├────────────────────────────────────────────────────────────────────┤
│ Driving access: CUSTOMER where grade = 'VIP' -> 120 rows           │
│      │                                                             │
│      ├─ row 1   -> ORDERS(customer_id) index lookup                │
│      ├─ row 2   -> ORDERS(customer_id) index lookup                │
│      ├─ row 3   -> ORDERS(customer_id) index lookup                │
│      └─ row 120 -> ORDERS(customer_id) index lookup                │
│                                                                    │
│ Good plan = small filtered outer + fast inner access               │
└────────────────────────────────────────────────────────────────────┘

중요한 오해 하나는 "원래 작은 테이블이 무조건 드라이빙"이라는 생각이다. 실제로는 기본 테이블 크기보다 필터 후 결과 건수가 더 중요하다. 예를 들어 주문 테이블이 5억 건이라도 order_date = today 조건으로 3,000건만 남는다면, 고객 테이블 1,000만 건보다 오히려 주문 쪽이 더 좋은 드라이빙이 될 수 있다.

또한 드라이빙/드리븐 개념은 조인 방식에 따라 다른 이름으로 나타나기도 한다. 해시 조인 (Hash Join)에서는 Build Input/Probe Input이라는 표현을 더 많이 쓰고, 소트 머지 조인 (Sort Merge Join)에서는 양쪽 정렬 후 병합이 핵심이 된다. 따라서 이 개념은 특정 키워드 암기가 아니라, 물리 조인이 어느 쪽을 먼저 줄이고 어느 쪽을 반복 접근하는지 보는 시각으로 기억해야 한다.

  • 📢 섹션 요약 비유: 드라이빙은 먼저 뽑아 놓는 손님 명단이고, 드리븐은 그 명단을 보고 매번 열어 보는 서류 캐비닛과 같다. 명단이 짧고 캐비닛 서랍이 잘 정리돼 있어야 일이 빨라진다.

Ⅲ. 비교 및 연결

드라이빙/드리븐을 제대로 이해하려면 비슷해 보이는 다른 개념과 경계를 분리해야 한다. 특히 SQL 작성 순서, 조인 순서 (Join Order), 해시 조인의 Build/Probe와 혼동하면 실행 계획 해석이 꼬인다.

개념무엇을 뜻하는가드라이빙/드리븐과의 관계
FROM 절 작성 순서사람이 SQL을 적은 문장 순서옵티마이저는 이를 바꿔 다른 드라이빙을 선택할 수 있음
조인 순서 (Join Order)여러 테이블을 어떤 순서로 묶을지드라이빙 선택은 조인 순서를 구성하는 핵심 결정
드라이빙 / 드리븐특정 물리 조인 단계의 바깥쪽/안쪽 역할중첩 루프 조인에서 특히 중요
Build / Probe해시 조인에서 해시 테이블 생성 쪽과 조회 쪽반복 조회의 방향을 본다는 점에서 유사하지만 동일 용어는 아님

가장 중요한 비교 포인트는 "작은 테이블"과 "작게 남는 테이블"의 차이다. 드라이빙 판단은 정적 크기 비교가 아니라, 조건 적용 후 남는 행 수를 보는 문제다. 이 때문에 선택도, 기수성, 분포도 같은 통계 정보가 조인 성능과 직접 연결된다.

또 하나의 연결점은 액세스 경로다. 드라이빙을 아무리 잘 골라도 드리븐에 적절한 인덱스가 없으면 반복 풀스캔이 벌어져 성능이 무너진다. 반대로 드리븐 인덱스가 매우 좋다면, 소량의 드라이빙 결과만 가지고도 매우 빠른 온라인 거래 처리 (OLTP, Online Transaction Processing) 질의를 만들 수 있다.

즉 드라이빙/드리븐은 독립된 단어쌍이 아니라, 선택도 → 기수성 추정 → 조인 순서 → 액세스 경로로 이어지는 옵티마이저 사고 흐름의 한 축이다. 이 연결이 보여야 "왜 해시 조인이 아니라 NL Join이 선택됐는가", "왜 힌트가 먹었는데도 느린가" 같은 질문에 답할 수 있다.

  • 📢 섹션 요약 비유: 먼저 만날 사람을 고르는 일과, 만난 뒤 주소록에서 집을 찾는 일은 다르다. 약속 인원이 적어도 주소록이 엉망이면 시간이 오래 걸리고, 주소록이 좋아도 약속 인원이 너무 많으면 하루가 모자란다.

Ⅳ. 실무 적용 및 기술사 판단

실무에서 드라이빙 테이블 판단은 "어느 테이블이 더 작으냐"보다 "어느 쪽을 먼저 읽으면 전체 탐색 횟수를 가장 많이 줄일 수 있느냐"로 내려야 한다. 예를 들어 CUSTOMER 1,000만 건, ORDERS 5억 건이 있어도 CUSTOMER.grade = 'VIP' 조건으로 200건만 남고 ORDERS.customer_id 인덱스가 잘 잡혀 있다면 CUSTOMER를 드라이빙으로 두는 것이 자연스럽다. 반대로 ORDERS.order_date = today로 3,000건만 남고 고객 조건이 약하다면, 훨씬 큰 원본 테이블이라도 ORDERS가 드라이빙이 될 수 있다.

힌트는 마지막 수단이어야 한다. Oracle 기준으로 LEADING, USE_NL 같은 힌트로 조인 순서를 고정할 수는 있지만, 통계가 오래됐거나 인덱스가 부적절한 상태를 힌트로 덮으면 특정 시점에만 빨랐던 실행 계획을 영구 고정하는 부작용이 생긴다. 먼저 할 일은 최신 통계 확보, 조건 푸시다운, 불필요 컬럼 제거, 드리븐 인덱스 정비다.

기술사 판단 체크리스트

  1. 각 후보 테이블의 필터 후 예상 건수는 얼마인가?
  2. 중첩 루프 조인이 유리한 소량 결과 질의인가?
  3. 드리븐 테이블의 조인 키 또는 결합 조건에 인덱스가 있는가?
  4. 비용 기반 옵티마이저 (CBO, Cost-Based Optimizer)가 참고하는 통계가 최신인가?
  5. 사람이 적은 FROM 순서를 실제 실행 순서로 오해하고 있지 않은가?
  6. 힌트를 쓰기 전에 조인 방식 자체가 맞는지 검토했는가?

자주 나오는 안티패턴

  • 원본 테이블 행 수만 보고 무조건 작은 테이블을 드라이빙으로 고정하는 경우
  • 드리븐 인덱스 없이 중첩 루프 조인을 강제로 유도하는 경우
  • FROM A, B에서 A를 먼저 썼다고 A가 항상 드라이빙이라고 믿는 경우
  • 통계 부정확 문제를 해결하지 않고 힌트로만 조인 순서를 봉인하는 경우

기술사 관점에서 기억할 핵심 문장은 이렇다. 드라이빙 테이블은 조인의 반복 횟수를 결정하고, 드리븐 테이블은 그 반복을 감당할 액세스 경로를 제공해야 한다. 둘 중 하나만 맞아도 부족하고, 둘이 함께 맞아야 실제 성능이 나온다.

  • 📢 섹션 요약 비유: 단체 관광에서 먼저 짜는 일정표가 곧 이동 횟수를 결정하고, 각 관광지의 출입구 구조가 실제 입장 속도를 결정한다. 일정표만 좋아도 안 되고, 출입구만 넓어도 안 된다.

Ⅴ. 기대효과 및 결론

드라이빙/드리븐 개념을 정확히 잡으면 실행 계획을 단순 암기에서 벗어나 구조적으로 읽을 수 있다. 어떤 질의가 느린지 볼 때도 "인덱스가 있나?"에서 끝나지 않고, 왜 이 집합이 반복의 바깥쪽으로 선택됐는가를 추적하게 된다. 그 결과 조인 성능 튜닝이 훨씬 예측 가능해진다.

기대효과는 명확하다. 적절한 드라이빙 선택은 반복 횟수를 줄이고, 적절한 드리븐 접근 경로는 반복당 비용을 낮춘다. 다만 한계도 있다. 대량 동등 조인에서는 해시 조인이 더 유리할 수 있고, 정렬된 결과가 중요하면 소트 머지 조인이 나을 수 있다. 즉 드라이빙/드리븐은 만능 정답이 아니라, 특히 NL Join을 읽고 튜닝할 때 가장 날카로운 관점이다.

결론적으로 이 개념은 "누가 먼저 읽히는가"보다 **"누가 반복 횟수를 만들고, 누가 그 반복을 빠르게 받아내는가"**로 기억하는 것이 정확하다. 이 한 줄이 잡히면 드라이빙 테이블은 단순 용어가 아니라 조인 성능의 핵심 제어 변수로 보이기 시작한다.

  • 📢 섹션 요약 비유: 좋은 조인 설계는 먼저 줄여야 할 손님 줄과, 그 손님을 빠르게 통과시킬 창구를 함께 고르는 일과 같다. 줄만 짧아도 창구가 막히면 느리고, 창구만 빨라도 줄이 너무 길면 여전히 오래 걸린다.

📌 관련 개념 맵

개념연결 포인트
중첩 루프 조인 (NL Join, Nested Loop Join)드라이빙/드리븐 개념이 가장 직접적으로 드러나는 조인 방식
선택도 (Selectivity)어떤 조건이 드라이빙 집합을 얼마나 작게 줄이는지 판단하는 기준
기수성 (Cardinality)필터 후 예상 행 수로, 조인 순서 결정의 핵심 입력
조인 순서 (Join Order)여러 테이블 조합에서 드라이빙 후보를 어떤 순서로 잡을지 정하는 문제
액세스 경로 (Access Path)드리븐 테이블이 인덱스 탐색인지 풀스캔인지 결정하는 요소
비용 기반 옵티마이저 (CBO, Cost-Based Optimizer)통계 정보를 기반으로 드라이빙/드리븐과 조인 방식을 선택하는 주체
해시 조인 (Hash Join)대량 동등 조인에서 NL Join 대신 고려되는 다른 물리 조인 방식

📈 관련 키워드 및 발전 흐름도

조건 선택도 파악
        │
        ▼
필터 후 기수성 추정
        │
        ▼
드라이빙 테이블 선택
        │
        ▼
드리븐 액세스 경로 결정
        │
        ▼
조인 반복 횟수 최소화
        │
        ▼
조인 순서 / 힌트 / 해시 조인 대안 검토

이 흐름은 "조건 분석 → 남는 행 수 추정 → 드라이빙 선택 → 드리븐 탐색 최적화 → 전체 조인 전략 확정"으로 이어지는 튜닝 사고 순서를 보여 준다.

👶 어린이를 위한 3줄 비유 설명

  1. 먼저 누구를 데리고 다닐지 정하면 하루에 몇 번 움직일지가 거의 결정돼요.
  2. 같이 다니는 친구가 적으면 문을 여는 횟수도 적어서 빨라져요.
  3. 그래서 조인에서는 먼저 고를 팀과, 그다음 빨리 찾을 서랍을 같이 잘 정해야 해요.