쿼리 옵티마이저 소개
한 문장 정의
Doris 쿼리 옵티마이저(Nereids)는 Cascades 프레임워크를 기반으로 구축된 현대적인 쿼리 옵티마이저입니다. RBO(규칙 기반 최적화)와 CBO(비용 기반 최적화)를 결합하여 복잡한 쿼리에 효율적인 실행 계획을 생성합니다.
읽기 안내
이 문서를 읽기 전에 다음 내용을 먼저 이해하는 것이 좋습니다.
- 데이터베이스 시스템에서 쿼리 옵티마이저의 기본 역할
- SQL 실행 계획의 기본 개념
- 규칙 기반 최적화(RBO)와 비용 기반 최적화(CBO)의 차이
이 문서에서는 다음 주제를 순서대로 다룹니다.
- 쿼리 옵티마이저의 개발 배경
- Doris 쿼리 옵티마이저의 핵심 장점
- 옵티마이저의 전반적인 동작 원리
- 자주 사용하는 튜닝용 세션 변수
개발 배경
현재 쿼리 옵티마이저는 다음 세 가지 과제에 직면해 있습니다.
| 과제 | 구체적인 양상 |
|---|---|
| 높은 쿼리 복잡성 | 사용자 쿼리가 점점 복잡해지고 쿼리 사용 시나리오도 다양해지고 있음 |
| 엄격한 실시간 요구 사항 | 사용자는 쿼리 결과를 즉시 얻기를 기대함 |
| 빠른 개선 주기 | 계속해서 등장하는 새로운 요구 사항에 옵티마이저가 신속하게 대응해야 함 |
이러한 배경에서 Doris는 완전히 새로운 쿼리 옵티마이저 개발에 착수했습니다. 현대적인 옵티마이저 아키텍처를 기반으로 구축된 이 옵티마이저는 Doris 사용 환경의 쿼리 요청을 더욱 효율적으로 처리하고, 향후 더 복잡한 요구 사항까지 지원할 수 있는 견고한 기반을 마련하는 것을 목표로 합니다.
Doris 쿼리 옵티마이저의 장점
Doris 쿼리 옵티마이저는 지능성, 안정성, 유연성이라는 세 가지 측면에서 기존 옵티마이저보다 뛰어난 장점을 제공합니다.
더 높은 지능성
- 옵티마이저는 RBO와 CBO의 각 최적화 요소를 "규칙" 형태로 명확하게 표현합니다.
- 각 규칙은 쿼리 계획의 형태를 설명하는 패턴 집합을 제공하므로, 옵티마이저는 최적화할 수 있는 쿼리 계획을 정확하게 찾아낼 수 있습니다.
- 이를 통해 여러 단계로 중첩된 서브쿼리와 같은 복잡한 쿼리 문을 더욱 잘 지원할 수 있습니다.
CBO 부분은 고급 Cascades 프레임워크를 기반으로 하며 다음 세 가지 정보를 충분히 활용합니다.
- 풍부한 데이터 통계
- 데이터 특성 정보
- 정교하게 튜닝된 비용 모델
이러한 정보를 활용하면 옵티마이저는 여러 테이블 간의 조인과 같은 복잡한 쿼리도 수월하게 처리할 수 있습니다.
더 높은 안정성
- 모든 최적화 규칙은 논리적 실행 계획 트리에서 적용됩니다.
- 쿼리의 구문과 의미를 분석한 후 쿼리를 트리 구조로 변환합니다.
- 새로운 옵티마이저의 내부 데이터 구조는 기존 옵티마이저보다 더 합리적이고 일관적입니다.
서브쿼리 처리를 예로 들면, 새로운 옵티마이저는 새로운 데이터 구조를 기반으로 하므로 기존 옵티마이저처럼 여러 규칙에서 서브쿼리를 개별적으로 처리하는 상황을 피할 수 있습니다. 이를 통해 최적화 규칙에서 논리 오류가 발생할 가능성을 줄입니다.
더 높은 유연성
옵티마이저는 체계적으로 설계된 현대적인 아키텍처를 갖추고 있어 최적화 규칙과 처리 단계를 쉽게 확장할 수 있습니다. 끊임없이 변화하는 요구 사항에 맞춰 새로운 기능을 빠르게 추가할 수 있습니다.
옵티마이저의 동작 원리
전체 처리 흐름

옵티마이저의 실행 흐름은 크게 다음 네 단계로 나눌 수 있습니다.
| 단계 | 처리 과정 | 설명 |
|---|---|---|
| 1 | 구문 분석 | SQL 텍스트를 추상 구문 트리(AST)로 변환합니다. SQL이 유효하면 다음 단계로 진행하고, 그렇지 않으면 오류를 보고하고 종료합니다 |
| 2 | 의미 분석 | AST에 있는 테이블, 컬럼, 함수가 존재하는지, 구문 및 의미 규칙에 맞게 사용되는지 확인합니다. 유효하면 다음 단계로 진행하고, 그렇지 않으면 오류를 보고하고 종료합니다 |
| 3 | 쿼리 계획 재작성(RBO) | 미리 정의된 규칙에 따라 쿼리 계획을 재작성합니다. 일반적인 기법으로는 컬럼 프루닝, 조건절 푸시다운, 파티션 프루닝이 있습니다 |
| 4 | 쿼리 계획 최적화(CBO) | 탐색 공간 내에서 동등한 계획 집합을 열거하고 각 계획의 실행 비용을 평가한 후, 비용이 가장 낮은 계획을 최종 실행 계획으로 선택합니다 |
각 단계의 목표는 다음과 같습니다.
- 구문 분석: SQL 텍스트를 유효한 AST로 파싱할 수 있는지 확인합니다.
- 의미 분석: AST에서 참조하는 객체가 존재하며 올바르게 사용되는지 확인합니다.
- RBO 재작성: 결정적인 규칙을 통해 실행 속도를 최적화합니다.
- CBO 최적화: 비용 모델을 기반으로 최적의 실행 계획을 선택하여 쿼리가 가장 효율적으로 실행되도록 합니다.
자주 사용하는 세션 변수
nereids_timeout_second
| 항목 | 내용 |
|---|---|
| 용도 | 쿼리 계획 수립에 허용되는 최대 시간을 설정합니다. 계획 수립 시간이 이 값을 초과하면 계획 수립을 중단하고 오류 메시지를 반환합니다 |
| 기본값 | 30s |
| 적용 시나리오 | 쿼리에 많은 외부 테이블이 포함되어 있거나 쿼리 문이 특히 복잡한 경우, 쿼리가 정상적으로 진행될 수 있도록 이 값을 적절히 늘립니다 |
설계 목적: 쿼리 문의 계획을 수립하는 동안 시스템은 SQL에 포함된 모든 테이블에 읽기 잠금을 획득합니다. 시간 제한을 설정하는 주요 목적은 다음과 같습니다.
- 클러스터 안정성 유지
- 지나치게 긴 계획 수립 시간으로 인한 과도한 리소스 소비 방지
- 잠금 충돌 방지
튜닝 권장 사항:
- 계획 수립 시간 초과 오류가 발생하면 먼저 SQL이 너무 복잡하거나 관련 테이블이 너무 많은지 확인합니다.
- 해당 시나리오가 타당한 것으로 확인되면
SET nereids_timeout_second = <seconds>;로 이 값을 늘립니다.