智能查询计划生成:AI 如何让数据库优化器跳出局部最优

📅 2026/6/27 2:46:00
智能查询计划生成:AI 如何让数据库优化器跳出局部最优
智能查询计划生成AI 如何让数据库优化器跳出局部最优一、传统优化器的天花板代价模型的系统性偏差数据库查询优化器本质是一个组合优化问题从等价的关系代数变换空间中找到代价最小的执行计划。传统优化器采用动态规划或贪心搜索在有限的搜索空间内寻找最优解。但这个搜索空间受两个硬约束限制一是启发式剪枝过早裁剪了潜在更优的执行路径二是代价模型对数据分布的建模精度不足。生产环境中的典型表现同一张表上三个可选索引优化器基于 Cardinality 估值选择了二级索引但实际执行时回表代价远超预期而主键范围扫描反而更快。这类问题在多表 JOIN 场景中更加严重——JOIN 顺序的排列组合随表数呈阶乘增长优化器在表数超过 6 时被迫降级为贪心搜索极易陷入局部最优。AI 驱动的查询优化正是针对这一瓶颈用机器学习模型替代或增强代价估算环节让优化器在更大的搜索空间中做出更准确的决策。二、AI 查询优化的三种架构路径当前学术界和工业界的 AI 查询优化方案可归纳为三种架构路径flowchart TB subgraph 传统优化器 A[SQL] -- B[语法解析] B -- C[代价模型] C -- D[执行计划] end subgraph 路径一: 代价模型增强 E1[SQL 特征提取] -- F1[ML 代价预测模型] F1 -- G1[替换/校准传统代价] G1 -- D end subgraph 路径二: 端到端计划生成 E2[SQL 编码] -- F2[Seq2Seq / GNN] F2 -- G2[直接输出 JOIN 顺序] G2 -- D end subgraph 路径三: 强化学习探索 E3[状态: 当前计划] -- F3[RL Agent] F3 -- G3[动作: 计划变换] G3 -- H3[奖励: 执行延迟] H3 -- F3 end A -.- E1 A -.- E2 A -.- E32.1 路径一代价模型增强Learned Cost Model核心思路保留传统优化器的搜索框架仅用 ML 模型替换代价估算函数。代表工作为 Microsoft 的 Learned Cardinality Estimator。优势改动最小可渐进式替换与现有优化器框架兼容。劣势搜索空间未扩展仍受启发式剪枝限制。2.2 路径二端到端计划生成核心思路将 SQL 查询编码为向量通过序列模型或图神经网络直接输出 JOIN 顺序和算子选择。代表工作为 Neo 的 RTOS 模型。优势搜索空间不受启发式限制。劣势训练数据需求大泛化到未见过的查询模式时表现不稳定。2.3 路径三强化学习探索核心思路将查询优化建模为马尔可夫决策过程Agent 通过与环境交互学习最优策略。状态为当前执行计划动作为计划变换操作交换 JOIN 顺序、更换索引等奖励为执行延迟的负值。优势可在线持续学习适应数据分布变化。劣势训练收敛慢冷启动阶段性能差生产环境直接部署风险高。三、代价模型增强的生产级实现以路径一为例实现一个基于梯度提升树的 Cardinality 估计模型import numpy as np import lightgbm as lgb from typing import List, Dict, Tuple import logging class LearnedCardinalityEstimator: 基于梯度提升树的基数估计器。 为什么选 LightGBM 而非神经网络 1. 表格数据上树模型精度通常优于 NN 2. 推理延迟低微秒级不影响优化器决策耗时 3. 特征可解释性强便于排查模型偏差 def __init__(self, model_path: str None): self.model None self.feature_columns [ table_rows, # 表总行数 index_cardinality, # 索引基数 num_range_predicates, # 范围谓词数量 num_eq_predicates, # 等值谓词数量 selectivity_estimate, # 传统优化器的选择性估值 histogram_skew, # 直方图偏度 correlation_with_pk, # 与主键的相关性 ] if model_path: self.load_model(model_path) def extract_features( self, query_context: Dict ) - np.ndarray: 从查询上下文中提取特征向量。 为什么不直接用 SQL 文本做特征 SQL 文本的高维稀疏性导致模型泛化差 结构化特征能更好地捕获基数与查询条件的关联。 features [] for col in self.feature_columns: val query_context.get(col, 0.0) features.append(float(val)) return np.array(features, dtypenp.float32) def train( self, train_features: np.ndarray, train_labels: np.ndarray, val_features: np.ndarray None, val_labels: np.ndarray None ): 训练基数预测模型。 标签为 log(实际行数)因为行数跨多个数量级 对数变换使模型在大小表上均有合理精度。 log_labels np.log1p(train_labels) params { objective: regression, metric: rmse, learning_rate: 0.05, num_leaves: 63, min_child_samples: 50, # 正则化防止过拟合确保对未见查询的泛化 lambda_l1: 0.1, lambda_l2: 0.2, feature_fraction: 0.8, } train_set lgb.Dataset(train_features, log_labels) valid_sets None if val_features is not None: val_set lgb.Dataset( val_features, np.log1p(val_labels), referencetrain_set ) valid_sets [val_set] self.model lgb.train( params, train_set, num_boost_round500, valid_setsvalid_sets, callbacks[ lgb.early_stopping(stopping_rounds30), lgb.log_evaluation(period50) ] ) logging.info( f模型训练完成特征数{len(self.feature_columns)} ) def predict(self, query_context: Dict) - float: 预测查询的基数行数。 返回 exp(prediction) - 1 还原对数变换。 if self.model is None: raise RuntimeError(模型未加载请先 train 或 load_model) features self.extract_features(query_context).reshape(1, -1) log_pred self.model.predict(features)[0] predicted_rows np.expm1(log_pred) # 下限保护预测值不能小于 1 return max(1.0, predicted_rows) def load_model(self, path: str): self.model lgb.Booster(model_filepath) def save_model(self, path: str): if self.model is None: raise RuntimeError(无可用模型) self.model.save_model(path)3.1 与优化器的集成方式生产环境中Learned Cardinality Estimator 不直接替换优化器而是作为校准层优化器先用传统代价模型生成候选计划。对每个候选计划用 ML 模型重新估算基数。若 ML 估算与传统估算偏差超过阈值如 50%以 ML 估算为准重新计算代价。选择代价最低的计划执行。这种双模型校验策略避免了 ML 模型冷启动时的灾难性错误。四、AI 优化器的落地瓶颈与适用边界4.1 训练数据的获取成本ML 代价模型需要大量查询-实际行数配对数据。在生产环境中采集这些数据需要在执行器层埋点记录每个算子的实际输出行数这会带来 3%-5% 的性能开销。对于延迟敏感的核心链路这个开销不可接受。4.2 分布漂移问题数据分布随业务变化而漂移ML 模型的预测精度会随时间衰减。实测数据模型训练后 2 周Q-Error预测值/实际值中位数从 1.3 上升到 2.1。需要建立模型监控和自动重训练流水线但这增加了系统复杂度。4.3 推理延迟约束优化器的决策时间通常在毫秒级。ML 模型的推理延迟必须控制在 1ms 以内否则会拖慢查询编译阶段。LightGBM 在 7 维特征上的推理延迟约 50us满足要求但若特征维度扩展到 100如编码 SQL 文本推理延迟可能超标。4.4 适用场景总结场景AI 优化器价值风险等级多表 JOIN6 表高扩展搜索空间中数据倾斜严重高修正基数偏差低查询模式固定中可用 FORCE INDEX 替代低查询模式多变高自适应选择高低延迟 OLTP低优化器耗时占比大高五、总结AI 查询优化的核心价值在于突破传统优化器的两个瓶颈搜索空间受限和代价模型精度不足。三种架构路径中代价模型增强方案改动最小、落地风险最低适合作为生产环境的切入点。端到端计划生成和强化学习方案潜力更大但训练数据需求、分布漂移和推理延迟三个问题尚未完全解决。落地路线建议第一步在从库上部署查询执行数据采集积累训练数据第二步训练 Learned Cardinality Estimator以影子模式运行仅记录预测结果不实际影响执行计划第三步对比 ML 预测与传统估算的偏差确认模型精度达标后逐步在校准层中启用 ML 估算。全程必须保留传统优化器作为降级兜底确保 AI 模型异常时不影响业务可用性。