Skip to main content

linkrs_query/optimizer/
engine.rs

1//! Optimizer Engine Module
2//!
3//! This module provides a query optimization engine, which is responsible for coordinating and managing all components related to query optimization.
4//!
5//! ## Design Specifications
6//!
7//! `OptimizerEngine` is the core component of the query optimization layer and is shared and used wherever it is needed through dependency injection.
8//! It integrates functions such as statistical information management, cost calculation, and selective estimation, providing a unified optimization service for the query pipeline.
9//!
10//! ## Explanation of Shared Instances
11//!
12//! The `OptimizerEngine` is designed to be a component that can be shared across multiple queries for the following reasons:
13//!
14//! 1. **Sharing of statistical information**: All queries share the same set of statistical information, ensuring consistency in cost estimates.
15//! 2. **Resource Efficiency**: Avoid the repeated creation of optimizer components in each query pipeline.
16//! 3. **Configuration Consistency**: A unified cost model configuration is applied to all queries.
17//!
18//! ## How to use it
19//!
20//! ```rust
21//! use std::sync::Arc;
22//! use linkrs_query::optimizer::cost::CostModelConfig;
23//! use linkrs_query::optimizer::engine::OptimizerEngine;
24//!
25//! // Created during the initialization of the database instance
26//! let optimizer_engine = Arc::new(OptimizerEngine::new(CostModelConfig::default()));
27//! ```
28//!
29//! ## Thread Safety
30//!
31//! `OptimizerEngine` utilizes `Arc` as well as thread-safe data structures, which allow for safe sharing in a multi-threaded environment.
32//!
33//! ## Attention
34//!
35//! This is not a global singleton, but an instance that is shared between components through `Arc`. Each database instance can have its own optimizer engine configuration.
36
37use std::sync::Arc;
38use std::sync::Mutex;
39
40use std::collections::HashMap;
41use std::sync::atomic::AtomicU64;
42
43use crate::optimizer::heuristic::batch::{BatchStatistics, OptimizationBatch};
44use crate::optimizer::heuristic::{LogicalBatchOptimizer, PhysicalHeuristicOptimizer};
45use crate::optimizer::partitioning::PartitioningPlanner;
46use crate::optimizer::stats::feedback::cardinality::CardinalityFeedbackManager;
47use crate::optimizer::stats::feedback::decision::DecisionFeedbackStore;
48use crate::optimizer::stats::feedback::history::QueryFeedbackHistory;
49use crate::optimizer::stats::feedback::selectivity::SelectivityFeedbackManager;
50use crate::optimizer::stats::feedback::trigger::AutoFeedbackTrigger;
51use crate::optimizer::{
52    BatchPlanAnalyzer, CostCalculator, CostModelConfig, CteCacheManager, SelectivityEstimator,
53    StatisticsManager, SubqueryUnnestingOptimizer,
54};
55use linkrs_core::types::expr::expression_context::ExpressionAnalysisContext;
56
57mod config;
58mod factorization;
59mod feedback;
60mod optimizer;
61
62#[cfg(test)]
63#[allow(unused_imports)]
64pub use config::*;
65#[allow(unused_imports)]
66pub use factorization::*;
67#[allow(unused_imports)]
68pub use optimizer::*;
69
70#[derive(Debug)]
71pub struct OptimizerEngine {
72    expression_context: Arc<ExpressionAnalysisContext>,
73    stats_manager: Arc<StatisticsManager>,
74    cte_cache_manager: Arc<CteCacheManager>,
75    cost_calculator: Arc<CostCalculator>,
76    selectivity_estimator: Arc<SelectivityEstimator>,
77    batch_plan_analyzer: BatchPlanAnalyzer,
78    subquery_unnesting_optimizer: SubqueryUnnestingOptimizer,
79    cost_config: CostModelConfig,
80    space_cost_configs: parking_lot::RwLock<HashMap<String, CostModelConfig>>,
81    space_calculators: parking_lot::RwLock<HashMap<String, Arc<CostCalculator>>>,
82    cost_epoch: AtomicU64,
83    logical_heuristic: LogicalBatchOptimizer,
84    physical_heuristic: PhysicalHeuristicOptimizer,
85    last_batch_statistics: Mutex<Vec<(OptimizationBatch, BatchStatistics)>>,
86    partitioning_planner: PartitioningPlanner,
87    enable_heuristic: bool,
88    max_heuristic_iterations: usize,
89    feedback_history: Arc<QueryFeedbackHistory>,
90    selectivity_feedback: Arc<SelectivityFeedbackManager>,
91    cardinality_feedback: Arc<CardinalityFeedbackManager>,
92    decision_feedback: Arc<DecisionFeedbackStore>,
93    feedback_trigger: AutoFeedbackTrigger,
94    enable_feedback: bool,
95    /// Highest folded history sequence per query fingerprint. The fold
96    /// loop consumes each execution exactly once; without this watermark
97    /// every optimization would re-apply the whole retained history and
98    /// walk the corrections again over identical samples.
99    feedback_applied_seq: parking_lot::Mutex<HashMap<String, u64>>,
100    columnar_policy: Arc<crate::executor::streaming::chunk::ColumnarPolicy>,
101    metrics_stats: Option<Arc<linkrs_metrics::StatsManager>>,
102}
103
104impl Default for OptimizerEngine {
105    fn default() -> Self {
106        Self::new(CostModelConfig::default())
107    }
108}
109
110#[cfg(test)]
111mod tests;