学习型查询优化器可以为复杂 SQL 提供候选计划或成本估计,但现阶段更适合放在传统优化器旁边做受控实验。数据库执行计划取决于统计信息、索引、连接顺序、数据分布和资源状态。模型即使在训练集上挑中了更快的计划,也可能在数据倾斜、参数变化或版本升级后给出很差的选择。
查询优化器到底在做什么
一条 SQL 往往有多种等价执行方式。优化器要决定先访问哪张表、使用索引还是顺序扫描、采用哪种连接算法,并估算每一步的代价。搜索空间会随表数量迅速扩大,因此传统系统依赖规则、统计信息和成本模型进行剪枝。学习方法常被用于补足代价估计或在候选计划之间排序。
为什么复杂查询特别难估价
列值分布不均、多个谓词相关、参数化查询和过期统计都会让行数估计偏离真实值。行数一旦偏小,优化器可能选择嵌套循环,实际执行时却反复访问大量记录。估得过大又可能提前选择哈希连接或排序,白白占用内存。模型能够从历史计划中学习模式,但它看不到未来数据变化。
如何把模型接进现有系统
先把它当成建议者,而非唯一决策者。运行环境应保留传统优化器生成的基准计划,并设置超时、资源上限和回退条件。
- 采集已脱敏的查询形状、统计摘要、计划与真实耗时。
- 按时间切分训练集和验证集,避免同一批数据同时训练和评估。
- 先离线比较候选计划的执行时间,而非只比较预测分数。
- 小流量启用,在超时或异常资源占用时自动回退。
离线评估还要覆盖冷缓存和热缓存。只看某一次运行,很容易把缓存命中当成计划质量。
评估指标该看什么
平均加速率很吸引人,尾部风险更重要。一次把原本几十毫秒的查询拖到几分钟,足以抵消很多小幅收益。团队应同时记录 P50、P95、P99、计划回退率、超时率和内存峰值,并按查询类别拆分结果。用于训练的工作负载与生产工作负载差异越大,结论越应保守。
运行中的边界条件
数据库版本、索引变更、统计信息刷新和参数类型变化都会改变计划分布。模型输入需要与优化器版本一起管理,特征缺失时应明确走回传统路径。涉及多租户数据时,训练样本还要处理敏感字段与跨租户泄露风险。把原始 SQL 全量长期保存通常没有必要。
FAQ
学习型优化器适合所有 SQL 吗
不适合。固定报表、简单主键查询和执行时间极短的语句,模型推理本身可能不划算。
统计信息还需要维护吗
需要。学习方法不能取代当前数据状态,传统统计仍是回退和诊断的重要依据。
给决策者的落地建议
先把优化目标限定为少数高成本、形状稳定的报表查询,并设定可接受的回退率与最长执行时间。训练与评估数据要隔离保存,避免把包含敏感业务字段的原始文本扩散到不必要的系统。每次上线数据库版本或索引策略前,都重新跑计划回归,不能沿用旧模型的成绩单。