深度指南 · 从模型成本走向实测证据

基于成本的优化器:从统计信息到执行计划与错误诊断

理解基于成本的优化器如何估算选择率与中间结果规模、比较访问路径和连接顺序,并用实际执行证据诊断统计偏差、参数敏感与错误计划。

更新于 2026 年 8 月 14 日阅读约17分钟深度指南InfiniSynapse
Cost based optimizer workflow using statistics and cardinality estimates to compare candidate plans, select a plan, and validate it with runtime feedback
本页目录
  1. 定义与快速回答
  2. CBO、规则与调优
  3. CBO工作流程
  4. 统计信息与选择率
  5. 成本模型与单位
  6. 计划枚举与剪枝
  7. 访问路径与连接
  8. CBO假设示例
  9. CBO错误选择原因
  10. 诊断工作流
  11. 参数与计划缓存
  12. 提示与计划稳定性
  13. 验证矩阵
  14. InfiniSynapse工具边界
  15. 常见问题
  16. 权威来源

什么是基于成本的优化器?

基于成本的优化器(CBO)是数据库中的决策引擎:它探索合法执行计划,估算每个候选方案的工作量,并在自身模型下选择所找到的最低成本计划。常见输入包括已绑定查询、Schema与索引、表与列统计信息、约束、分区、可用算子、成本常量和配置;输出则是可执行的物理计划。

“最低成本”并不承诺实际耗时一定最短。优化器只会搜索巨大计划空间中的有限子集,用估算而不是未来事实做判断,并以引擎特定单位表示资源权衡。当统计信息、参数、缓存状态、并发、内存或网络条件偏离假设时,所选计划即使在模型中合理,也可能表现很差。

基于成本与基于规则的优化有什么区别?

诊断计划前先区分决策方法
方法主要依据典型作用主要限制
正确性规则关系等价与合法性安全重写与验证不负责对运行方案排序
启发式或规则型固定优先级与搜索捷径规范化、简化与剪枝可能忽略数据分布
基于成本统计信息、估算与资源模型比较物理候选方案模型与估算可能错误
运行时自适应实测规模或执行反馈执行开始后调整产品与算子支持不一致

现代引擎通常组合这些方法。规则可以下推谓词或简化表达式,成本模型再比较扫描、连接与顺序,运行时逻辑还可能改变数据分布或连接策略。查询调优则是另一层:它是由人改进证据、修改受支持约束并验证结果的流程。把每个计划选择都归因于“只有CBO”,会掩盖重要边界。

基于成本的优化器如何工作

  1. 解析、绑定并确认合法性。

    引擎解析名称与类型、检查权限并生成内部表达式。SQL语法正确并不能证明业务语义正确或性能良好。

  2. 应用保持语义的转换。

    可能的重写包括常量折叠、子查询展开、视图合并、谓词移动与冗余操作消除;是否可用取决于引擎和查询形态。

  3. 估算选择率与基数。

    统计信息预测每个条件通过的行比例,以及算子之间流动的行数;这些估算向上传播并影响后续选择。

  4. 枚举物理候选方案。

    优化器考虑可用访问路径、连接顺序、连接算法、聚合、排序、物化、并行与分布方案,同时剪除被视为劣势或探索代价过高的候选方案。

  5. 估算成本、比较并生成计划。

    成本模型组合算子估算工作量与子计划成本,搜索过程保留更有希望的子计划;最终由停止条件或时间预算产出一个可执行计划。

统计信息是证据,不是数据副本

基于成本的优化器不能在规划时扫描每张表,因此依赖紧凑摘要:近似的表与索引大小、行数与页数、不同值数量、NULL比例、高频值、范围、直方图,有时还包括跨列相关性。约束与分区可以提供精确边界。许多系统通过抽样或定期任务刷新统计信息,所以即使刚更新的数据仍然是模型。

选择率回答“有多大比例通过”,基数回答“流出多少行”。在估算为一百万行的输入上,1%的谓词对应约一万行;同样的选择率用于一百行的小表,可能产生完全不同的访问路径选择。

单列直方图无法描述所有关系。城市与邮编、产品与类别、租户与状态都可能相关。如果模型把相关条件当作独立选择率相乘,行数估算可能过低或过高。在引擎支持时,可针对已证实的偏差创建多列统计信息;为所有列组合采集统计既不现实,也会增加维护成本。

查询计划成本不等于耗时

成本模型把估算工作量映射为可比较数值。根据引擎与算子不同,它可能表示顺序与随机页访问、行和表达式处理、索引遍历、排序、哈希、内存压力、临时I/O、并行启动、数据传输或远程往返。有些成本可配置,有些是内部实现;上层计划节点通常包含其所有子节点成本。

  • 启动成本估算首行输出前的工作,例如构建或排序输入。
  • 总成本估算节点被完整消费时的工作;LIMIT或提前停止会改变重要目标。
  • 成本单位主要只在同一优化上下文中有意义,不应直接换算成毫秒,也不应跨引擎比较。

修改全局成本常量是高影响操作。修复一个查询的值可能扭曲成千上万个其他查询。应先证明实际硬件、缓存或网络行为确实与模型严重不符,再测试代表性工作负载、记录作用范围并准备回滚路径。

计划枚举必须权衡搜索质量与规划时间

一个连接多张表的查询可能拥有大量合法连接树,而每棵树又可搭配多个访问路径、连接算法、排序策略、物化方案,以及并行或分布式变体。穷举成本可能超过执行查询本身,所以实际优化器会复用已知最佳子计划、限制转换、剪除劣势方案、应用启发式方法、在改进希望较小时停止,或对超大连接切换搜索策略。

因此,“优化器选择了最低成本”实际表示“在保留的候选方案中选择最低估算成本”,而不是在所有可想象计划中求得数学最小值。一个有希望的计划可能从未生成,也可能因早期基数错误让某个子计划显得昂贵而被剪枝。增加规划工作量可能改善选择,却也会增加编译延迟与计划缓存压力。

CBO如何选择访问路径、连接顺序与算法

常见选择取决于估算行数与运行环境
决策可能适用的情况可能失败的情况
索引查找或扫描符合条件行少、顺序有用或可覆盖数据大量随机查找、聚簇性差或选择率陈旧
全表或顺序扫描需要较大比例、表很小或顺序读取高效遗漏了高选择性的受支持路径
嵌套循环连接外部输入小且内部探测便宜外部基数被严重低估
哈希连接较大等值连接且构建端规模可控构建端溢写、倾斜或网络移动占主导
合并连接输入已排序或排序可服务后续工作所需排序成本高于其他方案

任何算子名称都不是天然好或坏。连接顺序控制中间结果规模,连接算法决定如何组合这些行,访问路径决定基础行如何到达。应结合实际行数、循环次数、读取、溢写、内存、网络、等待与并发评价完整计划。

DBMS中的基于成本优化:假设示例

以下数字仅为说明性示例,不是基准声明。假设一个查询连接`orders`、`customers`和`regions`。统计信息显示`orders`有两千万行,日期谓词保留5%,状态谓词保留10%。如果模型假设两个条件独立,就会预测十万条符合条件的订单,并可能选择以过滤后的订单为构建端进行哈希连接,再连接客户与区域。

但如果近期订单中“open”状态占比异常高,两个谓词组合后实际返回180万行,就出现十八倍低估。这可能导致哈希表溢写、改变适合的构建端、放大下一次连接并延迟首行。SQL没有变化,所选计划在原估算下也自洽;真正断裂的是描述相关性的证据链。

严谨处理方式是:在最早偏离节点比较估算行与实际行,检查统计信息年龄和抽样,调查倾斜与相关性,再测试受支持的目标统计或查询、设计替代方案。在理解估算前强制另一种连接,可能只会掩盖某个参数的症状,却在其他参数上失败。

为什么基于成本的优化器会选择错误计划

  • 统计信息陈旧或缺失:表增长、批量加载或分布变化没有进入模型。
  • 倾斜与相关性:平均值或列独立假设遗漏热点值与耦合谓词。
  • 未知表达式:函数、类型转换、变量或跨列表达式可能迫使引擎采用默认估算。
  • 参数敏感性:一个缓存计划被复用于需要显著不同访问路径的参数值。
  • 搜索剪枝:有用计划从未生成,或因早期误估而被删除。
  • 模型不匹配:配置的I/O、CPU、内存或网络假设不能代表实际负载。
  • 运行条件变化:并发、缓存、溢写、锁、远端可用性或自适应行为与编译时不同。

诊断CBO决策的可重复工作流

  1. 证明结果契约。

    比较速度前先固定预期行粒度、重复、NULL行为、排序、精度、时间边界与隔离要求。

  2. 定位最早的实质估算偏差。

    从基础访问向上阅读计划,结合循环次数比较估算行与实际行;后续错误可能只是结果。

  3. 解释估算来源。

    检查统计信息新鲜度、高频值、直方图边界、NULL、表达式、约束、相关性与参数可见性。

  4. 把偏差连接到物理选择。

    说明该估算如何影响扫描、连接顺序、连接算法、内存授予、并行或数据移动,避免调优无关节点。

  5. 一次测试一个受支持的处理方法。

    候选方法包括刷新或扩展统计信息、暴露可搜索谓词、修改有依据的索引或分区设计、处理参数类别,或应用范围受控的计划约束。

  6. 验证并监控。

    跨代表性参数类别比较结果、计划形态、实际工作量、重复延迟、资源、并发与波动,并定义回滚阈值。

参数敏感性会让一个好计划看起来很差

一个返回一行的谓词值与一个返回半张表的值,可能无法共享高效计划。编译时可能使用已知字面值、参数估算、平均分布或未知值默认值,随后缓存计划又服务后续执行。根据引擎不同,处理手段可能包括重编译行为、自定义与通用计划、参数敏感计划功能、查询变体、过滤结构或计划治理。

不要只测试慢字面值,也不要只测试平均值。应定义高频、罕见、空结果、近期范围、历史范围与租户极端等参数类别,记录每类参数获得的计划,并判断编译开销、缓存抖动或吞吐变化是否抵消延迟收益。

把提示与计划基线作为受治理约束

提示、计划指南、基线或强制计划,在事故、已知回归或严格控制的负载中可能有价值,但它们不是对成本模型的免费修复。固定访问路径可能在数据增长后失效,强制连接可能阻止新的优化器改进,计划基线也可能保留已经不再满足原假设的方案。

约束计划前,应记录观察到的失败、测试过的替代方案、受支持语法、准确版本范围、参数覆盖、负责人、监控信号、到期或复查日期与回滚方法。当修正已证实的证据或物理设计更安全且可维护时,应优先采用这些方式。

验证内容不能只有估算成本

计划变更的验收证据
维度测量内容失败信号
正确性行、重复、NULL、排序与汇总任何未经批准的语义差异
估算关键节点估算行与实际行实质偏差仍无法解释
执行读取、CPU、内存、溢写、网络与等待工作转移到另一个有害瓶颈
延迟与吞吐重复测试的中位数、尾延迟、吞吐与波动代表性参数类别出现回归
运维编译负载、缓存、写入、锁与发布变更不可观测或不可回滚

成本有助于解释优化器为什么偏好某个保留候选方案;实际证据才决定计划是否满足工作负载目标。应明确区分冷热缓存、客户端传输时间、并发和观察窗口,而不是把它们平均成一个看似安心的数字。

在引擎原生CBO测试前审查SQL结构

请准备经过脱敏的完整SQL,并确认预期方言。InfiniSynapse SQL Complexity Checker的可见功能会在浏览器中分析嵌套查询、CTE、连接、窗口函数、聚合与方言特定结构等模式,帮助安排哪些片段应优先由人工审查或检查计划。

该检查器不会执行SQL,不会检查表、索引或统计信息,不会枚举物理计划,也不会计算引擎原生成本或证明性能。复杂度评分是静态启发式结果,不是CBO输出。完成结构审查后,应回到目标数据库获取统计信息、估算与实际计划、代表性参数和受控基准。现有InfiniSynapse SQL查询优化指南提供更广泛的实用调优流程,本地查询优化指南则解释从优化器到验证的完整生命周期。

无需执行即可检查SQL结构

请移除凭据、密钥、个人数据与敏感字面值。粘贴脱敏语句并选择预期方言,以获得结构审查提示;任何性能结论都必须随后由引擎原生证据支持。

打开SQL复杂度检查器

基于成本的优化器常见问题

什么是基于成本的优化器?

基于成本的优化器是数据库中生成或探索合法执行计划、利用统计信息与成本模型估算每个候选方案工作量,并选择其找到的最低成本计划的组件。这个结果是由估算驱动的决策,不是对“实际运行必然最快”的证明。

基于成本的优化器如何工作?

它会转换已绑定的查询,估算谓词选择率与中间结果基数,枚举访问路径、连接顺序和物理算子,分配模型成本,剪枝搜索空间,并返回一个可执行计划。具体阶段与算法因数据库及版本而异。

基于成本的优化器会使用哪些统计信息?

常见输入包括表与索引大小、行数、不同值数量、NULL比例、高频值、直方图,有时还包括多列统计信息。引擎也可能使用约束、分区、物理排序、存储元数据、运行反馈与系统假设。

规则优化器与基于成本的优化器有什么区别?

规则优化器使用优先级规则或启发式方法,而不会通过数据敏感的成本模型比较所有候选方案;基于成本的优化器使用统计信息与建模后的资源工作量比较方案。现代系统通常组合正确性规则、启发式重写与基于成本的物理选择,而不是只采用一种方式。

为什么基于成本的优化器会选择慢计划?

陈旧或缺失的统计信息、数据倾斜、相关谓词、参数敏感性、难以估算的表达式、不完整搜索、与环境不匹配的成本常量、计划缓存复用,或运行条件偏离编译假设,都可能误导优化器。

更低的估算成本是否一定表示查询更快?

不一定。估算成本是引擎特定模型的输出,常使用抽象单位;它只在一组假设下比较候选方案,不是耗时,也通常不能跨引擎、版本或无关优化上下文比较。应使用安全的实际计划证据和代表性基准验证。

何时应使用优化器提示或计划基线?

只有在确认结果正确、复现错误选择、检查统计信息与受支持的设计修复,并测试代表性参数类别之后才考虑。提示或基线是受治理的约束,应有负责人、版本范围、监控和回滚,因为数据与优化器行为会变化。

InfiniSynapse SQL Complexity Checker能计算优化器成本吗?

不能。其可见功能只在浏览器中静态分析SQL结构和启发式复杂度;它不执行SQL,不检查Schema、索引或统计信息,不枚举引擎计划,也不计算引擎原生成本。可用它在数据库测试前安排结构审查优先级。

基于成本的优化器官方来源