学习型查询优化器:特征漂移比模型精度更麻烦
一、优化器引入模型后,问题不会自动变少
学习型查询优化器希望用机器学习改进基数估计、代价预测或计划选择。方向本身有价值,因为传统优化器在复杂谓词、相关列和数据倾斜场景下经常估错。但把模型引入优化器以后,系统多了新的不确定性:训练数据是否覆盖线上查询,特征是否稳定,数据分布是否漂移,错误计划如何兜底。
数据库优化器最重要的品质不是偶尔选择一个惊艳计划,而是长期稳定地避免灾难计划。学习型组件如果不能被约束,就可能在少数查询上带来巨大回退。优化器里不缺聪明,缺的是可解释和可兜底。
二、优化链路:模型只能参与部分决策
flowchart TD A[SQL 解析] --> B[逻辑计划] B --> C[候选物理计划] C --> D[特征抽取] D --> E[学习型代价模型] E --> F[计划选择] F --> G[执行反馈] G --> H[训练数据更新]学习型模型可以参与基数估计、成本修正或候选计划排序,但不应该绕过规则约束。比如不满足索引条件的计划不能被强行选择,内存超限的 hash join 不能只因为预测快就执行,跨分片查询不能忽略网络成本。规则负责边界,模型负责排序,这是比较稳妥的分工。
特征设计比模型选择更关键。表行数、列基数、直方图、谓词类型、join 图、索引覆盖、历史执行时间、缓存状态和并发负载都可能影响计划。但特征越多,漂移和采集成本越高。工程上要选择稳定、低成本、可解释的特征。
三、漂移检测:计划回退要可观测
下面是一个简化的执行反馈记录。它用于判断预测成本和实际耗时是否持续偏离。
{ "query_fingerprint": "select_orders_by_user_status", "chosen_plan": "idx_user_status_range_scan", "predicted_cost": 1820.5, "actual_latency_ms": 93.4, "actual_rows": 12890, "estimated_rows": 420, "feature_version": "v7" }如果估算行数和实际行数长期偏离,说明统计信息或模型特征存在问题。若某类 query fingerprint 的实际延迟持续高于预测,就要触发模型降权或回退到传统优化器。学习型组件必须有自我怀疑能力,否则它会把错误变成系统性问题。
灰度也要按查询类型进行。不要把模型优化器一次性放到全部 SQL 上。可以从只读分析查询开始,逐步扩展到复杂 join,再考虑交易查询。每一类查询都要记录计划变化率、性能提升分布和性能回退分布。平均值漂亮没有用,P99 回退会写进事故复盘。
四、上线边界:保护机制比模型结构更重要
学习型优化器上线需要至少三层保护。第一层是计划白名单或黑名单,避免选择已知危险计划。第二层是运行时资源限制,例如内存、临时文件和执行时间。第三层是反馈回滚,当实际执行明显偏离预测时,降低模型权重或切回传统代价模型。
还要处理冷启动。新表、新索引、新业务查询没有历史样本,模型容易失准。冷启动阶段应更多依赖传统统计信息,等积累足够执行反馈后再让模型参与。模型不是凭空知道新业务,它只是在历史分布上做预测。
最后,解释能力不能省。DBA 或内核工程师需要知道模型为什么偏好某个计划。即使无法完全解释复杂模型,也要输出关键特征、候选计划差异和预测置信度。优化器选错计划时,排障人员不能对着一个黑盒发呆。
五、总结
学习型查询优化器的难点不只是模型精度,更是特征稳定、分布漂移、错误兜底和可观测性。模型可以参与代价修正和计划排序,但必须受规则保护。数据库优化追求稳定收益,不追求不可解释的聪明。