쿼리 실행 연산자
쿼리 실행 연산자는 데이터베이스 엔진이 쿼리 결과를 생성하기 위해 계획을 구성하고 실행하는 물리적 알고리즘입니다. 여기에는 스캔, 선택, 투영, 정렬, 집계 및 조인이 포함됩니다.
Definition
쿼리 실행 연산자는 튜플 스트림에 대한 알고리즘으로서 관계형 대수 연산을 구현한 것입니다. 연산자들은 트리 또는 파이프라인으로 구성되며, 실행될 때 쿼리의 결과를 계산합니다.
Scope
이 주제는 쿼리 엔진의 물리적 연산자와 이들이 실행을 위해 어떻게 구성되는지를 다룹니다: 이터레이터(열기-다음-닫기) 모델, 파이프라이닝 대 구체화, 테이블 및 인덱스 스캔, 선택 및 투영, 외부 병합 정렬, 그룹화 및 집계, 중복 제거. 또한 연산자가 튜플 스트림을 소비하고 생성하는 방법과 메모리 및 I/O가 비용에 미치는 영향에 대해서도 다룹니다. 조인 알고리즘의 세부 사항과 연산자 선택을 담당하는 옵티마이저는 인접한 주제이므로 제외합니다.
Core questions
- 이터레이터(열기-다음-닫기) 모델은 연산자들이 어떻게 파이프라인으로 구성될 수 있도록 하는가?
- 결과가 언제 파이프라인으로 처리되거나 디스크로 구체화되는가?
- 선택, 투영, 중복 제거는 물리적으로 어떻게 구현되는가?
- 외부 병합 정렬은 메모리보다 큰 데이터를 어떻게 처리하는가?
- 메모리 예산과 I/O 비용이 연산자 성능에 어떻게 영향을 미치는가?
Key concepts
- 이터레이터 / 열기-다음-닫기 모델
- 테이블 및 인덱스 스캔
- 선택 및 투영 연산자
- 외부 병합 정렬
- 해시 기반 그룹화
- 집계 연산자
- 중복 제거
- 파이프라이닝 대 구체화
Key theories
- 이터레이터 (Volcano) 모델
- 각 연산자는 열기(open), 다음(next), 닫기(close) 메서드를 노출하고 필요에 따라 자식으로부터 튜플을 가져옵니다. 이 통일된 인터페이스는 임의의 연산자를 파이프라인으로 구성할 수 있게 하며 대부분의 쿼리 엔진의 기반이 됩니다.
- 파이프라이닝 대 구체화
- 파이프라인 연산자는 중간 결과를 기록하지 않고 튜플을 부모에게 직접 전달하여 I/O를 절약하는 반면, 정렬과 같은 블로킹 연산자는 출력을 생성하기 전에 입력을 구체화해야 합니다. 옵티마이저는 이 둘의 균형을 맞춥니다.
- 외부 정렬 및 집계
- 데이터가 메모리를 초과할 때, 외부 병합 정렬과 해시 기반 그룹화는 디스크를 통해 여러 번의 패스로 데이터를 처리합니다. 이러한 알고리즘은 ORDER BY, GROUP BY, 중복 제거 및 정렬-병합 조인의 기반이 됩니다.
Clinical relevance
실행 연산자는 쿼리 계획의 예상 비용이 실제 런타임이 되는 지점입니다. 연산자의 선택 및 구현, 그리고 메모리 사용 및 불필요한 디스크 I/O 회피 능력이 데이터베이스가 처리하는 모든 쿼리의 처리량과 지연 시간을 결정합니다.
History
이터레이터 모델은 Graefe의 Volcano 쿼리 평가 프레임워크와 관계형 엔진에서 사용되는 물리적 연산자를 분류한 그의 1993년 쿼리 평가 기술 조사에서 구체화되었습니다. 이 모델의 통일된 인터페이스는 확장 가능하고 구성 가능한 쿼리 엔진을 실용적으로 만들었으며, 이후 더 큰 효율성을 위해 벡터화되고 컴파일된 실행을 추가하는 작업과 함께 표준으로 남아 있습니다.
Key figures
- Goetz Graefe
- Jeffrey D. Ullman
Related topics
Seminal works
- graefe1993
- garciamolina2008
Frequently asked questions
- 이터레이터 모델이란 무엇인가?
- 이는 모든 물리적 연산자가 동일한 인터페이스(일반적으로 열기, 다음, 닫기)를 구현하고, 부모가 다음을 호출할 때 한 번에 하나의 튜플을 생성하는 설계입니다. 모든 연산자가 이 인터페이스를 공유하기 때문에 임의의 계획 트리로 연결될 수 있으며, 튜플은 필요에 따라 트리를 따라 위로 흐릅니다.
- 일부 연산자를 블로킹이라고 부르는 이유는 무엇인가?
- 블로킹 연산자는 모든 입력을 소비하기 전까지는 어떤 출력도 생성할 수 없습니다. 정렬 및 특정 집계가 그 예시인데, 최종 결과가 모든 입력 튜플에 의존하기 때문입니다. 블로킹 연산자는 입력을 구체화해야 하는 반면, 선택과 같은 파이프라인 연산자는 진행하면서 결과를 내보낼 수 있습니다.