Skip to main content

dbx_core/sql/optimizer/
mod.rs

1//! SQL 쿼리 옵티마이저 — 규칙 기반 최적화
2//!
3//! LogicalPlan을 최적화하여 실행 성능을 향상시킵니다.
4//! 4가지 핵심 규칙: PredicatePushdown, ProjectionPushdown, ConstantFolding, LimitPushdown
5
6mod constant_folding;
7mod distributed_pushdown;
8mod limit_pushdown;
9mod predicate_pushdown;
10mod projection_pushdown;
11mod subquery_unnesting;
12mod tier_pruning;
13
14#[cfg(test)]
15mod tests;
16
17use crate::error::DbxResult;
18use crate::sql::planner::LogicalPlan;
19
20pub use constant_folding::ConstantFoldingRule;
21pub use distributed_pushdown::DistributedPushdownRule;
22pub use limit_pushdown::LimitPushdownRule;
23pub use predicate_pushdown::PredicatePushdownRule;
24pub use projection_pushdown::ProjectionPushdownRule;
25pub use subquery_unnesting::SubqueryUnnestingRule;
26pub use tier_pruning::TierPruningRule;
27
28/// 최적화 규칙 트레이트
29pub trait OptimizationRule: Send + Sync {
30    /// 규칙 이름
31    fn name(&self) -> &str;
32
33    /// LogicalPlan에 규칙 적용
34    fn apply(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan>;
35}
36
37/// 쿼리 옵티마이저
38pub struct QueryOptimizer {
39    rules: Vec<Box<dyn OptimizationRule>>,
40}
41
42impl QueryOptimizer {
43    /// 기본 최적화 규칙으로 생성
44    pub fn new() -> Self {
45        Self {
46            rules: vec![
47                Box::new(SubqueryUnnestingRule), // 가장 먼저 서브쿼리 해제
48                Box::new(PredicatePushdownRule),
49                Box::new(ProjectionPushdownRule),
50                Box::new(ConstantFoldingRule),
51                Box::new(DistributedPushdownRule),
52                Box::new(LimitPushdownRule),
53            ],
54        }
55    }
56
57    /// 외부 구성 규칙 등록 (Phase 6 MetadataRegistry 연계 등)
58    pub fn register_rule(&mut self, rule: Box<dyn OptimizationRule>) {
59        // 푸루닝 규칙은 보통 푸시다운 이전/이후에 실행. 여기서는 맨 마지막(또는 첫번째)에 추가
60        self.rules.push(rule);
61    }
62
63    /// 모든 규칙 적용
64    pub fn optimize(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan> {
65        let mut optimized = plan;
66        for rule in &self.rules {
67            optimized = rule.apply(optimized)?;
68        }
69        Ok(optimized)
70    }
71}
72
73impl Default for QueryOptimizer {
74    fn default() -> Self {
75        Self::new()
76    }
77}