본문 바로가기
🔍 CS/데이터베이스

12/18 - TIL : Driving, Driven

by 컴쏘 2024. 12. 18.

 

DrivingDriven은 일반적으로 주도하는 역할주도 당하는 역할을 의미한다. 기술적인 맥락에서 보면 다음과 같다. 

  • Driving : 시스템 또는 구조에서 주요 동작을 결정하거나 제어하는 주체를 의미한다. 
    • ex. 절차적 프로그래밍이나 명령형 프로그래밍에서 개발자가 프로그램의 흐름을 직접 제어(if - else 문 등을 사용하여 프로그램의 흐름을 직접 설계)하며 드라이빙 역할을 수행
  • Driven : 시스템에서 외부 입력이나 특정 조건에 의해 동작하는 대상을 의미한다. 
    • ex. Event-Driven Architecture : 특정 이벤트가 발생하면 동작을 수행하는 시스템, 외부 요청에 의해 실행되는 구조로 드리븐 상태이다. 

 

Database드라이빙드리븐은 무엇일까? 

 

| Join 에서의 Driving 과 Driven 

데이터베이스에서 Join 연산2개 이상의 테이블을 결합하여 데이터를 가져오는 작업이다. 

이 과정에서 어떤 테이블이 Driving 테이블인지 어떤 테이블이 Driven 테이블인지 결정하는 쿼리 최적화의 중요한 부분이다. 

 

 

일반적으로 작은 데이터 세트 또는 효율적인 인덱스가 있는 테이블Driving 테이블로 선택된다. 

  • Join 시 먼저 엑세스 되어 Access Path(접근 경로)를 주도하는 테이블이다.

 

Driven 테이블은 Driving 테이블에 의해 검색되는 테이블이다. 

  • Driving 테이블의 결과를 기준으로 필요한 데이터를 가져온다. 
  • 일반적으로 큰 데이터 세트Join의 대상이 되는 테이블이 Driven 테이블로 선택된다. 

 

간단한 예시를 들어보면 다음과 같다. 

 

1000만건의 데이터를 가진 A 테이블1000건의 데이터를 가진 B 테이블을 조인할 때 드라이빙 순서에 따라 성능의 차이가 크다고 한다.

  • 1000만 건의 A 테이블을 먼저 Driving 하면 1000만 번을 반복하며 B 테이블을 탐색한다. 
  • 하지만, 1000 건의 B 테이블을 먼저 Driving 하면 1000 번의 A 테이블이 탐색된다. 

따라서, 작업 대상이 되는 rows의 수가 적은 테이블부터 액세스 되어야 전체 탐색이 줄어든다는 것이다. 

 

 

 

Driving, Driven의 결정 요인에 대해 조금 더 알아보면, 다음과 같다. 

 

DBMS는 쿼리 실행 계획을 수립할 때 드라이빙 테이블과 드리븐 테이블을 결정하게 된다. 

  • 테이블 크기 : 작은 테이블이 Driving 테이블로 선택되는 경우가 많다. 
  • 인덱스 여부 : 인덱스가 있는 테이블을 Driven 테이블로 두면 Driving 테이블이 Driven 테이블에 의해 반복적으로 Full Scan 하지 않아 더 빠르다. 한 쪽에만 인덱스가 있다면 인덱스가 없는 테이블을 Driving 테이블로 하게 된다. 

 

실제 실행 계획에서의 표현은 어떨까? 

 

SQL의 실행 계획을 확인하면 드라이빙과 드리븐의 관계를 파악할 수 있다. 일반적으로 DBMS는 Nested Loop Join, Hash Join, 또는 Merge Join 과 같은 방식으로 두 테이블을 결합한다. 

  • Nested Loop Join : 한 테이블(Driving)을 읽고, 다른 테이블(Driven)을 반복적으로 검색한다.
    • Driving 테이블의 각 행에 대해 Driven 테이블에서 매칭되는 행을 검색한다.
    • 일반적으로 작은 Driving 테이블인덱스가 있는 Driven 테이블에서 효율적이다. 
  • Block Nested Loop Join : Driving 테이블의 데이터를 Join Buffer에 저장한다.
    • Driving 테이블에서 조건에 맞는 데이터를 검색 후 Join 버퍼에 저장하고, Join 버퍼와 Driven 테이블의 데이터를 비교한다.
    • Driven 테이블한 번의 Full Scan으로 데이터를 처리한다. Driven 테이블의 Full Scan 횟수를 줄여 성능을 개선하는 방식이다. 
  • Batched Key Access Join : 랜덤 액세스 비효율을 줄이고, Sequential 액세스를 수행한다. 
    • Driven 테이블에 필요한 데이터를 미리 에측하고 정렬된 상태로 담는 Random Buffer라는 개념이 도입된다. 
    • Driving 테이블에서 데이터를 Join Buffer에 적재한다. 
    • Driven 테이블에서 필요한 데이터를 예측하고 Random Buffer에 저장한다. 
    • Random Buffer데이터를 정렬된 상태로 담아 Sequential Access를 수행한다. 
    • Join BufferRandom Buffer 데이터를 비교한 후, 동일한 데이터가 있다고 판단되면 Driven 테이블의 데이터가 접근하고 결과를 조인하여 반환한다. 
    • 다중 범위 읽기 Driven 테이블의 데이터를 미리 정렬하여 효율적인 읽기를 수행한다. 따라서, Driven 테이블의 랜덤 액세스를 줄이고 성능을 향상시킨다. 
  • Hash Join : Hash 테이블을 생성하여 조인, Driving 테이블의 데이터를 기준으로 Hash를 만들고, Driven 테이블의 데이터를 매핑한다. 
    • 해시 값을 생성하여 Join을 수행한다. Join 열에 인덱스가 필요 없으며, 동등 비교 연산에 적합하다. 
    • 각 테이블의 데이터를 해시값으로 변환하여 해시 값을 기반으로 내부 조인을 수행한다. 
    • 결과를 조인 버퍼에 저장한 후 반환하기 때문에 대용량 데이터 처리에 적합하다. 
    • 해시 값 생성에 시간이 소요되기 때문에 적은양의 데이터 조인에는 비효율적이다.